#include "shlguid.h"
#include "idispids.h"
+#define NO_SHLWAPI_REG
+#include "shlwapi.h"
+
#include "wine/debug.h"
-#include "wine/unicode.h"
#include "mshtml_private.h"
#include "htmlevent.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+/* Undocumented notification, see tests */
+#define CMDID_EXPLORER_UPDATEHISTORY 38
+
typedef struct {
task_t header;
HTMLDocumentObj *doc;
LPOLESTR url;
} download_proc_task_t;
-static BOOL use_gecko_script(HTMLWindow *window)
+static BOOL use_gecko_script(HTMLOuterWindow *window)
{
DWORD zone;
HRESULT hres;
- static const WCHAR aboutW[] = {'a','b','o','u','t',':'};
-
hres = IInternetSecurityManager_MapUrlToZone(window->secmgr, window->url, &zone, 0);
if(FAILED(hres)) {
WARN("Could not map %s to zone: %08x\n", debugstr_w(window->url), hres);
}
TRACE("zone %d\n", zone);
- return zone != URLZONE_LOCAL_MACHINE && zone != URLZONE_TRUSTED
- && strncmpiW(aboutW, window->url, sizeof(aboutW)/sizeof(WCHAR));
+ return zone == URLZONE_UNTRUSTED;
}
-void set_current_mon(HTMLWindow *This, IMoniker *mon)
+static void notify_travellog_update(HTMLDocumentObj *doc)
{
+ IOleCommandTarget *cmdtrg;
+ HRESULT hres;
+
+ if(!doc->is_webbrowser)
+ return;
+
+ /* Don't notify if we were in about: page */
+ if(doc->basedoc.window->uri) {
+ DWORD scheme;
+
+ hres = IUri_GetScheme(doc->basedoc.window->uri, &scheme);
+ if(SUCCEEDED(hres) && scheme == URL_SCHEME_ABOUT)
+ return;
+ }
+
+ hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
+ if(SUCCEEDED(hres)) {
+ VARIANT vin;
+
+ V_VT(&vin) = VT_I4;
+ V_I4(&vin) = 0;
+
+ IOleCommandTarget_Exec(cmdtrg, &CGID_Explorer, CMDID_EXPLORER_UPDATEHISTORY, 0, &vin, NULL);
+ IOleCommandTarget_Release(cmdtrg);
+ }
+}
+
+void set_current_uri(HTMLOuterWindow *window, IUri *uri)
+{
+ if(window->uri) {
+ IUri_Release(window->uri);
+ window->uri = NULL;
+ }
+
+ SysFreeString(window->url);
+ window->url = NULL;
+
+ if(!uri)
+ return;
+
+ IUri_AddRef(uri);
+ window->uri = uri;
+
+ IUri_GetDisplayUri(uri, &window->url);
+}
+
+void set_current_mon(HTMLOuterWindow *This, IMoniker *mon)
+{
+ IUriContainer *uri_container;
+ IUri *uri = NULL;
HRESULT hres;
if(This->mon) {
+ if(This->doc_obj)
+ notify_travellog_update(This->doc_obj);
IMoniker_Release(This->mon);
This->mon = NULL;
}
- if(This->url) {
- CoTaskMemFree(This->url);
- This->url = NULL;
- }
-
if(!mon)
return;
IMoniker_AddRef(mon);
This->mon = mon;
- hres = IMoniker_GetDisplayName(mon, NULL, NULL, &This->url);
- if(FAILED(hres))
- WARN("GetDisplayName failed: %08x\n", hres);
+ hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container);
+ if(SUCCEEDED(hres)) {
+ hres = IUriContainer_GetIUri(uri_container, &uri);
+ IUriContainer_Release(uri_container);
+ if(hres != S_OK) {
+ WARN("GetIUri failed: %08x\n", hres);
+ uri = NULL;
+ }
+ }
+
+ if(!uri) {
+ WCHAR *url;
+
+ hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url);
+ if(SUCCEEDED(hres)) {
+ hres = CreateUri(url, 0, 0, &uri);
+ if(FAILED(hres)) {
+ WARN("CrateUri failed: %08x\n", hres);
+ set_current_uri(This, NULL);
+ This->url = SysAllocString(url);
+ CoTaskMemFree(url);
+ return;
+ }
+ CoTaskMemFree(url);
+ }else {
+ WARN("GetDisplayName failed: %08x\n", hres);
+ }
+ }
+ set_current_uri(This, uri);
+ if(uri)
+ IUri_Release(uri);
set_script_mode(This, use_gecko_script(This) ? SCRIPTMODE_GECKO : SCRIPTMODE_ACTIVESCRIPT);
}
+HRESULT create_relative_uri(HTMLOuterWindow *window, const WCHAR *rel_uri, IUri **uri)
+{
+ return window->uri
+ ? CoInternetCombineUrlEx(window->uri, rel_uri, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, uri, 0)
+ : CreateUri(rel_uri, 0, 0, uri);
+}
+
void set_download_state(HTMLDocumentObj *doc, int state)
{
if(doc->client) {
IDropTarget *drop_target = NULL;
hres = IDocHostUIHandler_GetDropTarget(doc->hostui, NULL /* FIXME */, &drop_target);
- if(drop_target) {
+ if(SUCCEEDED(hres) && drop_target) {
FIXME("Use IDropTarget\n");
IDropTarget_Release(drop_target);
}
heap_free(task);
}
-void prepare_for_binding(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BOOL navigated_binding)
+void prepare_for_binding(HTMLDocument *This, IMoniker *mon, BOOL navigated_binding)
{
HRESULT hres;
hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
if(SUCCEEDED(hres)) {
if(V_VT(&silent) != VT_BOOL)
- WARN("V_VT(silent) = %d\n", V_VT(&silent));
+ WARN("silent = %s\n", debugstr_variant(&silent));
else if(V_BOOL(&silent))
FIXME("silent == true\n");
}
DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &offline);
if(SUCCEEDED(hres)) {
if(V_VT(&offline) != VT_BOOL)
- WARN("V_VT(offline) = %d\n", V_VT(&offline));
+ WARN("offline = %s\n", debugstr_variant(&offline));
else if(V_BOOL(&offline))
FIXME("offline == true\n");
}
IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL);
}else {
V_VT(&var) = VT_UNKNOWN;
- V_UNKNOWN(&var) = (IUnknown*)&This->window->IHTMLWindow2_iface;
+ V_UNKNOWN(&var) = (IUnknown*)&This->window->base.IHTMLWindow2_iface;
V_VT(&out) = VT_EMPTY;
hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 63, 0, &var, &out);
if(SUCCEEDED(hres))
if(SUCCEEDED(hres)) {
remove_target_tasks(This->task_magic);
- abort_document_bindings(This->doc_node);
+ abort_window_bindings(This->window->base.inner_window);
hres = load_nsuri(This->window, nsuri, bscallback, 0/*LOAD_INITIAL_DOCUMENT_URI*/);
nsISupports_Release((nsISupports*)nsuri); /* FIXME */
if(SUCCEEDED(hres))
- set_window_bscallback(This->window, bscallback);
+ hres = create_pending_window(This->window, bscallback);
if(bscallback != async_bsc)
- IUnknown_Release((IUnknown*)bscallback);
+ IUnknown_Release(&bscallback->bsc.IBindStatusCallback_iface);
}
if(FAILED(hres)) {
return S_OK;
}
-void set_ready_state(HTMLWindow *window, READYSTATE readystate)
+void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate)
{
window->readystate = readystate;
if(window->doc_obj && window->doc_obj->basedoc.window == window)
call_property_onchanged(&window->doc_obj->basedoc.cp_propnotif, DISPID_READYSTATE);
- fire_event(window->doc, EVENTID_READYSTATECHANGE, FALSE, window->doc->node.nsnode, NULL);
+ fire_event(window->base.inner_window->doc, EVENTID_READYSTATECHANGE, FALSE, window->base.inner_window->doc->node.nsnode, NULL);
if(window->frame_element)
fire_event(window->frame_element->element.node.doc, EVENTID_READYSTATECHANGE,
LPCWSTR strw;
nsAString nsstr;
nsresult nsres;
+ HRESULT hres;
if(!This->nsdoc) {
WARN("NULL nsdoc\n");
}
nsAString_Init(&nsstr, NULL);
- nsnode_to_nsstring(nsnode, &nsstr);
+ hres = nsnode_to_nsstring(nsnode, &nsstr);
nsIDOMNode_Release(nsnode);
+ if(FAILED(hres)) {
+ nsAString_Finish(&nsstr);
+ return hres;
+ }
nsAString_GetData(&nsstr, &strw);
TRACE("%s\n", debugstr_w(strw));
nsAString_Finish(&nsstr);
+ if(!*str)
+ return E_OUTOFMEMORY;
return S_OK;
}
}
}
- prepare_for_binding(This, pimkName, pibc, FALSE);
+ prepare_for_binding(This, pimkName, FALSE);
+ call_docview_84(This->doc_obj);
hres = set_moniker(This, pimkName, pibc, NULL, TRUE);
if(FAILED(hres))
return hres;
- return start_binding(This->window, NULL, (BSCallback*)This->window->bscallback, pibc);
+ return start_binding(This->window, This->window->pending_window, (BSCallback*)This->window->pending_window->bscallback, pibc);
}
static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName,
return hres;
}
- prepare_for_binding(This, mon, NULL, FALSE);
+ prepare_for_binding(This, mon, FALSE);
hres = set_moniker(This, mon, NULL, NULL, TRUE);
IMoniker_Release(mon);
if(FAILED(hres))
return hres;
- return channelbsc_load_stream(This->window->bscallback, pStm);
+ return channelbsc_load_stream(This->window->pending_window, pStm);
}
static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm,
return hres;
}
- prepare_for_binding(This, mon, NULL, FALSE);
+ prepare_for_binding(This, mon, FALSE);
hres = set_moniker(This, mon, NULL, NULL, FALSE);
IMoniker_Release(mon);
if(FAILED(hres))
return hres;
- return channelbsc_load_stream(This->window->bscallback, NULL);
+ return channelbsc_load_stream(This->window->pending_window, NULL);
}
static const IPersistStreamInitVtbl PersistStreamInitVtbl = {