2 * Copyright 2005 Jacek Caban
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define WIN32_NO_STATUS
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
33 //#include "winuser.h"
38 #define NO_SHLWAPI_REG
41 #include <wine/debug.h>
43 #include "mshtml_private.h"
44 #include "htmlscript.h"
45 #include "htmlevent.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
51 /* Undocumented notification, see tests */
52 #define CMDID_EXPLORER_UPDATEHISTORY 38
54 static const WCHAR about_blankW
[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
61 } download_proc_task_t
;
63 static BOOL
use_gecko_script(HTMLOuterWindow
*window
)
68 hres
= IInternetSecurityManager_MapUrlToZone(window
->secmgr
, window
->url
, &zone
, 0);
70 WARN("Could not map %s to zone: %08x\n", debugstr_w(window
->url
), hres
);
74 TRACE("zone %d\n", zone
);
75 return zone
== URLZONE_UNTRUSTED
;
78 static void notify_travellog_update(HTMLDocumentObj
*doc
)
80 IOleCommandTarget
*cmdtrg
;
83 if(!doc
->is_webbrowser
)
86 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&cmdtrg
);
93 IOleCommandTarget_Exec(cmdtrg
, &CGID_Explorer
, CMDID_EXPLORER_UPDATEHISTORY
, 0, &vin
, NULL
);
94 IOleCommandTarget_Release(cmdtrg
);
98 void set_current_uri(HTMLOuterWindow
*window
, IUri
*uri
)
101 IUri_Release(window
->uri
);
105 if(window
->uri_nofrag
) {
106 IUri_Release(window
->uri_nofrag
);
107 window
->uri_nofrag
= NULL
;
110 SysFreeString(window
->url
);
119 window
->uri_nofrag
= get_uri_nofrag(uri
);
120 if(!window
->uri_nofrag
) {
121 FIXME("get_uri_nofrag failed\n");
123 window
->uri_nofrag
= uri
;
126 IUri_GetDisplayUri(uri
, &window
->url
);
129 void set_current_mon(HTMLOuterWindow
*This
, IMoniker
*mon
, DWORD flags
)
131 IUriContainer
*uri_container
;
136 if(This
->doc_obj
&& !(flags
& (BINDING_REPLACE
|BINDING_REFRESH
)))
137 notify_travellog_update(This
->doc_obj
);
138 IMoniker_Release(This
->mon
);
142 This
->load_flags
= flags
;
146 IMoniker_AddRef(mon
);
149 hres
= IMoniker_QueryInterface(mon
, &IID_IUriContainer
, (void**)&uri_container
);
150 if(SUCCEEDED(hres
)) {
151 hres
= IUriContainer_GetIUri(uri_container
, &uri
);
152 IUriContainer_Release(uri_container
);
154 WARN("GetIUri failed: %08x\n", hres
);
162 hres
= IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
163 if(SUCCEEDED(hres
)) {
164 hres
= CreateUri(url
, 0, 0, &uri
);
166 WARN("CrateUri failed: %08x\n", hres
);
167 set_current_uri(This
, NULL
);
168 This
->url
= SysAllocString(url
);
174 WARN("GetDisplayName failed: %08x\n", hres
);
178 set_current_uri(This
, uri
);
181 set_script_mode(This
, use_gecko_script(This
) ? SCRIPTMODE_GECKO
: SCRIPTMODE_ACTIVESCRIPT
);
184 HRESULT
create_relative_uri(HTMLOuterWindow
*window
, const WCHAR
*rel_uri
, IUri
**uri
)
187 ? CoInternetCombineUrlEx(window
->uri
, rel_uri
, URL_ESCAPE_SPACES_ONLY
|URL_DONT_ESCAPE_EXTRA_INFO
, uri
, 0)
188 : CreateUri(rel_uri
, 0, 0, uri
);
191 void set_download_state(HTMLDocumentObj
*doc
, int state
)
194 IOleCommandTarget
*olecmd
;
197 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
198 if(SUCCEEDED(hres
)) {
204 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETDOWNLOADSTATE
,
205 OLECMDEXECOPT_DONTPROMPTUSER
, &var
, NULL
);
206 IOleCommandTarget_Release(olecmd
);
210 doc
->download_state
= state
;
213 static void set_progress_proc(task_t
*_task
)
215 docobj_task_t
*task
= (docobj_task_t
*)_task
;
216 IOleCommandTarget
*olecmd
= NULL
;
217 HTMLDocumentObj
*doc
= task
->doc
;
220 TRACE("(%p)\n", doc
);
223 IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
226 VARIANT progress_max
, progress
;
228 V_VT(&progress_max
) = VT_I4
;
229 V_I4(&progress_max
) = 0; /* FIXME */
230 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSMAX
, OLECMDEXECOPT_DONTPROMPTUSER
,
231 &progress_max
, NULL
);
233 V_VT(&progress
) = VT_I4
;
234 V_I4(&progress
) = 0; /* FIXME */
235 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSPOS
, OLECMDEXECOPT_DONTPROMPTUSER
,
237 IOleCommandTarget_Release(olecmd
);
240 if(doc
->usermode
== EDITMODE
&& doc
->hostui
) {
241 DOCHOSTUIINFO hostinfo
;
243 memset(&hostinfo
, 0, sizeof(DOCHOSTUIINFO
));
244 hostinfo
.cbSize
= sizeof(DOCHOSTUIINFO
);
245 hres
= IDocHostUIHandler_GetHostInfo(doc
->hostui
, &hostinfo
);
247 /* FIXME: use hostinfo */
248 TRACE("hostinfo = {%u %08x %08x %s %s}\n",
249 hostinfo
.cbSize
, hostinfo
.dwFlags
, hostinfo
.dwDoubleClick
,
250 debugstr_w(hostinfo
.pchHostCss
), debugstr_w(hostinfo
.pchHostNS
));
254 static void set_downloading_proc(task_t
*_task
)
256 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
257 HTMLDocumentObj
*doc
= task
->doc
;
260 TRACE("(%p)\n", doc
);
262 set_statustext(doc
, IDS_STATUS_DOWNLOADINGFROM
, task
->url
);
264 if(task
->set_download
)
265 set_download_state(doc
, 1);
271 IAdviseSink_OnViewChange(doc
->view_sink
, DVASPECT_CONTENT
, -1);
274 IDropTarget
*drop_target
= NULL
;
276 hres
= IDocHostUIHandler_GetDropTarget(doc
->hostui
, NULL
/* FIXME */, &drop_target
);
277 if(SUCCEEDED(hres
) && drop_target
) {
278 FIXME("Use IDropTarget\n");
279 IDropTarget_Release(drop_target
);
284 static void set_downloading_task_destr(task_t
*_task
)
286 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
288 CoTaskMemFree(task
->url
);
292 void prepare_for_binding(HTMLDocument
*This
, IMoniker
*mon
, DWORD flags
)
296 if(This
->doc_obj
->client
) {
297 VARIANT silent
, offline
;
299 hres
= get_client_disp_property(This
->doc_obj
->client
, DISPID_AMBIENT_SILENT
, &silent
);
300 if(SUCCEEDED(hres
)) {
301 if(V_VT(&silent
) != VT_BOOL
)
302 WARN("silent = %s\n", debugstr_variant(&silent
));
303 else if(V_BOOL(&silent
))
304 FIXME("silent == true\n");
307 hres
= get_client_disp_property(This
->doc_obj
->client
,
308 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED
, &offline
);
309 if(SUCCEEDED(hres
)) {
310 if(V_VT(&offline
) != VT_BOOL
)
311 WARN("offline = %s\n", debugstr_variant(&offline
));
312 else if(V_BOOL(&offline
))
313 FIXME("offline == true\n");
317 if(This
->window
->mon
) {
318 update_doc(This
, UPDATE_TITLE
|UPDATE_UI
);
320 update_doc(This
, UPDATE_TITLE
);
321 set_current_mon(This
->window
, mon
, flags
);
324 if(This
->doc_obj
->client
) {
325 IOleCommandTarget
*cmdtrg
= NULL
;
327 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
329 if(SUCCEEDED(hres
)) {
332 if(flags
& BINDING_NAVIGATED
) {
333 V_VT(&var
) = VT_UNKNOWN
;
334 V_UNKNOWN(&var
) = (IUnknown
*)&This
->window
->base
.IHTMLWindow2_iface
;
335 V_VT(&out
) = VT_EMPTY
;
336 hres
= IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 63, 0, &var
, &out
);
339 }else if(!(flags
& BINDING_FROMHIST
)) {
342 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 37, 0, &var
, NULL
);
345 IOleCommandTarget_Release(cmdtrg
);
350 HRESULT
set_moniker(HTMLDocument
*This
, IMoniker
*mon
, IBindCtx
*pibc
, nsChannelBSC
*async_bsc
, BOOL set_download
)
352 download_proc_task_t
*download_task
;
353 nsChannelBSC
*bscallback
;
358 hres
= IMoniker_GetDisplayName(mon
, pibc
, NULL
, &url
);
360 WARN("GetDiaplayName failed: %08x\n", hres
);
364 TRACE("got url: %s\n", debugstr_w(url
));
366 set_ready_state(This
->window
, READYSTATE_LOADING
);
368 hres
= create_doc_uri(This
->window
, url
, &nsuri
);
369 if(SUCCEEDED(hres
)) {
371 bscallback
= async_bsc
;
373 hres
= create_channelbsc(mon
, NULL
, NULL
, 0, TRUE
, &bscallback
);
376 if(SUCCEEDED(hres
)) {
377 remove_target_tasks(This
->task_magic
);
378 abort_window_bindings(This
->window
->base
.inner_window
);
380 hres
= load_nsuri(This
->window
, nsuri
, bscallback
, 0/*LOAD_INITIAL_DOCUMENT_URI*/);
381 nsISupports_Release((nsISupports
*)nsuri
); /* FIXME */
383 hres
= create_pending_window(This
->window
, bscallback
);
384 if(bscallback
!= async_bsc
)
385 IBindStatusCallback_Release(&bscallback
->bsc
.IBindStatusCallback_iface
);
393 HTMLDocument_LockContainer(This
->doc_obj
, TRUE
);
395 if(This
->doc_obj
->frame
) {
398 task
= heap_alloc(sizeof(docobj_task_t
));
399 task
->doc
= This
->doc_obj
;
400 hres
= push_task(&task
->header
, set_progress_proc
, NULL
, This
->doc_obj
->basedoc
.task_magic
);
407 download_task
= heap_alloc(sizeof(download_proc_task_t
));
408 download_task
->doc
= This
->doc_obj
;
409 download_task
->set_download
= set_download
;
410 download_task
->url
= url
;
411 return push_task(&download_task
->header
, set_downloading_proc
, set_downloading_task_destr
, This
->doc_obj
->basedoc
.task_magic
);
414 void set_ready_state(HTMLOuterWindow
*window
, READYSTATE readystate
)
416 window
->readystate
= readystate
;
418 if(window
->doc_obj
&& window
->doc_obj
->basedoc
.window
== window
)
419 call_property_onchanged(&window
->doc_obj
->basedoc
.cp_container
, DISPID_READYSTATE
);
421 fire_event(window
->base
.inner_window
->doc
, EVENTID_READYSTATECHANGE
, FALSE
,
422 window
->base
.inner_window
->doc
->node
.nsnode
, NULL
, NULL
);
424 if(window
->frame_element
)
425 fire_event(window
->frame_element
->element
.node
.doc
, EVENTID_READYSTATECHANGE
,
426 TRUE
, window
->frame_element
->element
.node
.nsnode
, NULL
, NULL
);
429 static HRESULT
get_doc_string(HTMLDocumentNode
*This
, char **str
)
438 WARN("NULL nsdoc\n");
442 nsres
= nsIDOMHTMLDocument_QueryInterface(This
->nsdoc
, &IID_nsIDOMNode
, (void**)&nsnode
);
443 if(NS_FAILED(nsres
)) {
444 ERR("Could not get nsIDOMNode failed: %08x\n", nsres
);
448 nsAString_Init(&nsstr
, NULL
);
449 hres
= nsnode_to_nsstring(nsnode
, &nsstr
);
450 nsIDOMNode_Release(nsnode
);
452 nsAString_Finish(&nsstr
);
456 nsAString_GetData(&nsstr
, &strw
);
457 TRACE("%s\n", debugstr_w(strw
));
459 *str
= heap_strdupWtoA(strw
);
461 nsAString_Finish(&nsstr
);
464 return E_OUTOFMEMORY
;
469 /**********************************************************
470 * IPersistMoniker implementation
473 static inline HTMLDocument
*impl_from_IPersistMoniker(IPersistMoniker
*iface
)
475 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistMoniker_iface
);
478 static HRESULT WINAPI
PersistMoniker_QueryInterface(IPersistMoniker
*iface
, REFIID riid
, void **ppv
)
480 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
481 return htmldoc_query_interface(This
, riid
, ppv
);
484 static ULONG WINAPI
PersistMoniker_AddRef(IPersistMoniker
*iface
)
486 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
487 return htmldoc_addref(This
);
490 static ULONG WINAPI
PersistMoniker_Release(IPersistMoniker
*iface
)
492 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
493 return htmldoc_release(This
);
496 static HRESULT WINAPI
PersistMoniker_GetClassID(IPersistMoniker
*iface
, CLSID
*pClassID
)
498 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
499 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
502 static HRESULT WINAPI
PersistMoniker_IsDirty(IPersistMoniker
*iface
)
504 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
506 TRACE("(%p)\n", This
);
508 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
511 static HRESULT WINAPI
PersistMoniker_Load(IPersistMoniker
*iface
, BOOL fFullyAvailable
,
512 IMoniker
*pimkName
, LPBC pibc
, DWORD grfMode
)
514 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
517 TRACE("(%p)->(%x %p %p %08x)\n", This
, fFullyAvailable
, pimkName
, pibc
, grfMode
);
520 IUnknown
*unk
= NULL
;
524 * "__PrecreatedObject"
525 * "BIND_CONTEXT_PARAM"
526 * "__HTMLLOADOPTIONS"
529 * "_ITransData_Object_"
533 hres
= IBindCtx_GetObjectParam(pibc
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
, &unk
);
534 if(SUCCEEDED(hres
) && unk
) {
535 IOleClientSite
*client
= NULL
;
537 hres
= IUnknown_QueryInterface(unk
, &IID_IOleClientSite
, (void**)&client
);
538 if(SUCCEEDED(hres
)) {
539 TRACE("Got client site %p\n", client
);
540 IOleObject_SetClientSite(&This
->IOleObject_iface
, client
);
541 IOleClientSite_Release(client
);
544 IUnknown_Release(unk
);
548 prepare_for_binding(This
, pimkName
, FALSE
);
549 call_docview_84(This
->doc_obj
);
550 hres
= set_moniker(This
, pimkName
, pibc
, NULL
, TRUE
);
554 return start_binding(This
->window
->pending_window
, (BSCallback
*)This
->window
->pending_window
->bscallback
, pibc
);
557 static HRESULT WINAPI
PersistMoniker_Save(IPersistMoniker
*iface
, IMoniker
*pimkName
,
558 LPBC pbc
, BOOL fRemember
)
560 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
561 FIXME("(%p)->(%p %p %x)\n", This
, pimkName
, pbc
, fRemember
);
565 static HRESULT WINAPI
PersistMoniker_SaveCompleted(IPersistMoniker
*iface
, IMoniker
*pimkName
, LPBC pibc
)
567 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
568 FIXME("(%p)->(%p %p)\n", This
, pimkName
, pibc
);
572 static HRESULT WINAPI
PersistMoniker_GetCurMoniker(IPersistMoniker
*iface
, IMoniker
**ppimkName
)
574 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
576 TRACE("(%p)->(%p)\n", This
, ppimkName
);
578 if(!This
->window
|| !This
->window
->mon
)
581 IMoniker_AddRef(This
->window
->mon
);
582 *ppimkName
= This
->window
->mon
;
586 static const IPersistMonikerVtbl PersistMonikerVtbl
= {
587 PersistMoniker_QueryInterface
,
588 PersistMoniker_AddRef
,
589 PersistMoniker_Release
,
590 PersistMoniker_GetClassID
,
591 PersistMoniker_IsDirty
,
594 PersistMoniker_SaveCompleted
,
595 PersistMoniker_GetCurMoniker
598 /**********************************************************
599 * IMonikerProp implementation
602 static inline HTMLDocument
*impl_from_IMonikerProp(IMonikerProp
*iface
)
604 return CONTAINING_RECORD(iface
, HTMLDocument
, IMonikerProp_iface
);
607 static HRESULT WINAPI
MonikerProp_QueryInterface(IMonikerProp
*iface
, REFIID riid
, void **ppv
)
609 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
610 return htmldoc_query_interface(This
, riid
, ppv
);
613 static ULONG WINAPI
MonikerProp_AddRef(IMonikerProp
*iface
)
615 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
616 return htmldoc_addref(This
);
619 static ULONG WINAPI
MonikerProp_Release(IMonikerProp
*iface
)
621 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
622 return htmldoc_release(This
);
625 static HRESULT WINAPI
MonikerProp_PutProperty(IMonikerProp
*iface
, MONIKERPROPERTY mkp
, LPCWSTR val
)
627 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
629 TRACE("(%p)->(%d %s)\n", This
, mkp
, debugstr_w(val
));
633 heap_free(This
->doc_obj
->mime
);
634 This
->doc_obj
->mime
= heap_strdupW(val
);
641 FIXME("mkp %d\n", mkp
);
648 static const IMonikerPropVtbl MonikerPropVtbl
= {
649 MonikerProp_QueryInterface
,
652 MonikerProp_PutProperty
655 /**********************************************************
656 * IPersistFile implementation
659 static inline HTMLDocument
*impl_from_IPersistFile(IPersistFile
*iface
)
661 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistFile_iface
);
664 static HRESULT WINAPI
PersistFile_QueryInterface(IPersistFile
*iface
, REFIID riid
, void **ppv
)
666 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
667 return htmldoc_query_interface(This
, riid
, ppv
);
670 static ULONG WINAPI
PersistFile_AddRef(IPersistFile
*iface
)
672 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
673 return htmldoc_addref(This
);
676 static ULONG WINAPI
PersistFile_Release(IPersistFile
*iface
)
678 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
679 return htmldoc_release(This
);
682 static HRESULT WINAPI
PersistFile_GetClassID(IPersistFile
*iface
, CLSID
*pClassID
)
684 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
686 TRACE("(%p)->(%p)\n", This
, pClassID
);
691 *pClassID
= CLSID_HTMLDocument
;
695 static HRESULT WINAPI
PersistFile_IsDirty(IPersistFile
*iface
)
697 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
699 TRACE("(%p)\n", This
);
701 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
704 static HRESULT WINAPI
PersistFile_Load(IPersistFile
*iface
, LPCOLESTR pszFileName
, DWORD dwMode
)
706 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
707 FIXME("(%p)->(%s %08x)\n", This
, debugstr_w(pszFileName
), dwMode
);
711 static HRESULT WINAPI
PersistFile_Save(IPersistFile
*iface
, LPCOLESTR pszFileName
, BOOL fRemember
)
713 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
719 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(pszFileName
), fRemember
);
721 file
= CreateFileW(pszFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
722 FILE_ATTRIBUTE_NORMAL
, NULL
);
723 if(file
== INVALID_HANDLE_VALUE
) {
724 WARN("Could not create file: %u\n", GetLastError());
728 hres
= get_doc_string(This
->doc_node
, &str
);
730 WriteFile(file
, str
, strlen(str
), &written
, NULL
);
736 static HRESULT WINAPI
PersistFile_SaveCompleted(IPersistFile
*iface
, LPCOLESTR pszFileName
)
738 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
739 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFileName
));
743 static HRESULT WINAPI
PersistFile_GetCurFile(IPersistFile
*iface
, LPOLESTR
*pszFileName
)
745 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
746 FIXME("(%p)->(%p)\n", This
, pszFileName
);
750 static const IPersistFileVtbl PersistFileVtbl
= {
751 PersistFile_QueryInterface
,
754 PersistFile_GetClassID
,
758 PersistFile_SaveCompleted
,
759 PersistFile_GetCurFile
762 static inline HTMLDocument
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
764 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistStreamInit_iface
);
767 static HRESULT WINAPI
PersistStreamInit_QueryInterface(IPersistStreamInit
*iface
,
768 REFIID riid
, void **ppv
)
770 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
771 return htmldoc_query_interface(This
, riid
, ppv
);
774 static ULONG WINAPI
PersistStreamInit_AddRef(IPersistStreamInit
*iface
)
776 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
777 return htmldoc_addref(This
);
780 static ULONG WINAPI
PersistStreamInit_Release(IPersistStreamInit
*iface
)
782 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
783 return htmldoc_release(This
);
786 static HRESULT WINAPI
PersistStreamInit_GetClassID(IPersistStreamInit
*iface
, CLSID
*pClassID
)
788 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
789 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
792 static HRESULT WINAPI
PersistStreamInit_IsDirty(IPersistStreamInit
*iface
)
794 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
796 TRACE("(%p)\n", This
);
798 if(This
->doc_obj
->usermode
== EDITMODE
)
799 return editor_is_dirty(This
);
804 static HRESULT WINAPI
PersistStreamInit_Load(IPersistStreamInit
*iface
, LPSTREAM pStm
)
806 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
810 TRACE("(%p)->(%p)\n", This
, pStm
);
812 hres
= CreateURLMoniker(NULL
, about_blankW
, &mon
);
814 WARN("CreateURLMoniker failed: %08x\n", hres
);
818 prepare_for_binding(This
, mon
, FALSE
);
819 hres
= set_moniker(This
, mon
, NULL
, NULL
, TRUE
);
820 IMoniker_Release(mon
);
824 return channelbsc_load_stream(This
->window
->pending_window
, pStm
);
827 static HRESULT WINAPI
PersistStreamInit_Save(IPersistStreamInit
*iface
, LPSTREAM pStm
,
830 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
835 TRACE("(%p)->(%p %x)\n", This
, pStm
, fClearDirty
);
837 hres
= get_doc_string(This
->doc_node
, &str
);
841 hres
= IStream_Write(pStm
, str
, strlen(str
), &written
);
843 FIXME("Write failed: %08x\n", hres
);
848 set_dirty(This
, VARIANT_FALSE
);
853 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(IPersistStreamInit
*iface
,
854 ULARGE_INTEGER
*pcbSize
)
856 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
857 FIXME("(%p)->(%p)\n", This
, pcbSize
);
861 static HRESULT WINAPI
PersistStreamInit_InitNew(IPersistStreamInit
*iface
)
863 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
867 TRACE("(%p)\n", This
);
869 hres
= CreateURLMoniker(NULL
, about_blankW
, &mon
);
871 WARN("CreateURLMoniker failed: %08x\n", hres
);
875 prepare_for_binding(This
, mon
, FALSE
);
876 hres
= set_moniker(This
, mon
, NULL
, NULL
, FALSE
);
877 IMoniker_Release(mon
);
881 return channelbsc_load_stream(This
->window
->pending_window
, NULL
);
884 static const IPersistStreamInitVtbl PersistStreamInitVtbl
= {
885 PersistStreamInit_QueryInterface
,
886 PersistStreamInit_AddRef
,
887 PersistStreamInit_Release
,
888 PersistStreamInit_GetClassID
,
889 PersistStreamInit_IsDirty
,
890 PersistStreamInit_Load
,
891 PersistStreamInit_Save
,
892 PersistStreamInit_GetSizeMax
,
893 PersistStreamInit_InitNew
896 /**********************************************************
897 * IPersistHistory implementation
900 static inline HTMLDocument
*impl_from_IPersistHistory(IPersistHistory
*iface
)
902 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistHistory_iface
);
905 static HRESULT WINAPI
PersistHistory_QueryInterface(IPersistHistory
*iface
, REFIID riid
, void **ppv
)
907 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
908 return htmldoc_query_interface(This
, riid
, ppv
);
911 static ULONG WINAPI
PersistHistory_AddRef(IPersistHistory
*iface
)
913 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
914 return htmldoc_addref(This
);
917 static ULONG WINAPI
PersistHistory_Release(IPersistHistory
*iface
)
919 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
920 return htmldoc_release(This
);
923 static HRESULT WINAPI
PersistHistory_GetClassID(IPersistHistory
*iface
, CLSID
*pClassID
)
925 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
926 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
929 static HRESULT WINAPI
PersistHistory_LoadHistory(IPersistHistory
*iface
, IStream
*pStream
, IBindCtx
*pbc
)
931 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
937 TRACE("(%p)->(%p %p)\n", This
, pStream
, pbc
);
940 FIXME("No current window\n");
945 FIXME("pbc not supported\n");
947 if(This
->doc_obj
->client
) {
948 IOleCommandTarget
*cmdtrg
= NULL
;
950 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
952 if(SUCCEEDED(hres
)) {
953 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 138, 0, NULL
, NULL
);
954 IOleCommandTarget_Release(cmdtrg
);
958 hres
= IStream_Read(pStream
, &str_len
, sizeof(str_len
), &read
);
961 if(read
!= sizeof(str_len
))
964 uri_str
= heap_alloc((str_len
+1)*sizeof(WCHAR
));
966 return E_OUTOFMEMORY
;
968 hres
= IStream_Read(pStream
, uri_str
, str_len
*sizeof(WCHAR
), &read
);
969 if(SUCCEEDED(hres
) && read
!= str_len
*sizeof(WCHAR
))
971 if(SUCCEEDED(hres
)) {
972 uri_str
[str_len
] = 0;
973 hres
= CreateUri(uri_str
, 0, 0, &uri
);
979 hres
= load_uri(This
->window
, uri
, BINDING_FROMHIST
);
984 static HRESULT WINAPI
PersistHistory_SaveHistory(IPersistHistory
*iface
, IStream
*pStream
)
986 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
991 TRACE("(%p)->(%p)\n", This
, pStream
);
993 if(!This
->window
|| !This
->window
->uri
) {
994 FIXME("No current URI\n");
998 /* NOTE: The format we store is *not* compatible with native MSHTML. We currently
999 * store only URI of the page (as a length followed by a string) */
1000 hres
= IUri_GetDisplayUri(This
->window
->uri
, &display_uri
);
1004 len
= SysStringLen(display_uri
);
1005 hres
= IStream_Write(pStream
, &len
, sizeof(len
), &written
);
1007 hres
= IStream_Write(pStream
, display_uri
, len
*sizeof(WCHAR
), &written
);
1008 SysFreeString(display_uri
);
1012 static HRESULT WINAPI
PersistHistory_SetPositionCookie(IPersistHistory
*iface
, DWORD dwPositioncookie
)
1014 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1015 FIXME("(%p)->(%x)\n", This
, dwPositioncookie
);
1019 static HRESULT WINAPI
PersistHistory_GetPositionCookie(IPersistHistory
*iface
, DWORD
*pdwPositioncookie
)
1021 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1022 FIXME("(%p)->(%p)\n", This
, pdwPositioncookie
);
1026 static const IPersistHistoryVtbl PersistHistoryVtbl
= {
1027 PersistHistory_QueryInterface
,
1028 PersistHistory_AddRef
,
1029 PersistHistory_Release
,
1030 PersistHistory_GetClassID
,
1031 PersistHistory_LoadHistory
,
1032 PersistHistory_SaveHistory
,
1033 PersistHistory_SetPositionCookie
,
1034 PersistHistory_GetPositionCookie
1037 void HTMLDocument_Persist_Init(HTMLDocument
*This
)
1039 This
->IPersistMoniker_iface
.lpVtbl
= &PersistMonikerVtbl
;
1040 This
->IPersistFile_iface
.lpVtbl
= &PersistFileVtbl
;
1041 This
->IMonikerProp_iface
.lpVtbl
= &MonikerPropVtbl
;
1042 This
->IPersistStreamInit_iface
.lpVtbl
= &PersistStreamInitVtbl
;
1043 This
->IPersistHistory_iface
.lpVtbl
= &PersistHistoryVtbl
;