From fbdfec74b04ee4fd627892102da026f90aba9d04 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 15 Nov 2011 13:30:28 +0100 Subject: [PATCH] mshtml: Properly handle fragment-only navigation. --- dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/navigate.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/nsiface.idl | 30 +++++++++++++++++++++++++++++- dlls/mshtml/nsio.c | 2 +- dlls/mshtml/persist.c | 2 +- 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 0915977b1c2..625fc524c29 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -671,6 +671,7 @@ void release_nsio(void) DECLSPEC_HIDDEN; BOOL is_gecko_path(const char*) DECLSPEC_HIDDEN; HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*) DECLSPEC_HIDDEN; +BOOL compare_ignoring_frag(IUri*,IUri*) DECLSPEC_HIDDEN; HRESULT navigate_url(HTMLWindow*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; HRESULT set_frame_doc(HTMLFrameBase*,nsIDOMDocument*) DECLSPEC_HIDDEN; @@ -700,6 +701,7 @@ nsresult get_nsinterface(nsISupports*,REFIID,void**) DECLSPEC_HIDDEN; void set_window_bscallback(HTMLWindow*,nsChannelBSC*) DECLSPEC_HIDDEN; void set_current_mon(HTMLWindow*,IMoniker*) DECLSPEC_HIDDEN; +void set_current_uri(HTMLWindow*,IUri*) DECLSPEC_HIDDEN; HRESULT start_binding(HTMLWindow*,HTMLDocumentNode*,BSCallback*,IBindCtx*) DECLSPEC_HIDDEN; HRESULT async_start_doc_binding(HTMLWindow*,nsChannelBSC*) DECLSPEC_HIDDEN; void abort_document_bindings(HTMLDocumentNode*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index ea1c650e2b5..bb97ee11040 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1766,6 +1766,45 @@ static void navigate_task_destr(task_t *_task) heap_free(task); } +static HRESULT navigate_fragment(HTMLWindow *window, IUri *uri) +{ + nsIDOMLocation *nslocation; + nsAString nsfrag_str; + BSTR frag; + nsresult nsres; + HRESULT hres; + + set_current_uri(window, uri); + + nsres = nsIDOMWindow_GetLocation(window->nswindow, &nslocation); + if(FAILED(nsres) || !nslocation) + return E_FAIL; + + hres = IUri_GetFragment(uri, &frag); + if(FAILED(hres)) { + nsIDOMLocation_Release(nslocation); + return hres; + } + + nsAString_InitDepend(&nsfrag_str, frag); + nsres = nsIDOMLocation_SetHash(nslocation, &nsfrag_str); + nsAString_Finish(&nsfrag_str); + nsIDOMLocation_Release(nslocation); + SysFreeString(frag); + if(NS_FAILED(nsres)) { + ERR("SetHash failed: %08x\n", nsres); + return E_FAIL; + } + + if(window->doc_obj->doc_object_service) { + IDocObjectService_FireNavigateComplete2(window->doc_obj->doc_object_service, &window->IHTMLWindow2_iface, 0x10); + IDocObjectService_FireDocumentComplete(window->doc_obj->doc_object_service, &window->IHTMLWindow2_iface, 0); + + } + + return S_OK; +} + HRESULT super_navigate(HTMLWindow *window, IUri *uri, const WCHAR *headers, BYTE *post_data, DWORD post_data_size) { nsChannelBSC *bsc; @@ -1796,6 +1835,11 @@ HRESULT super_navigate(HTMLWindow *window, IUri *uri, const WCHAR *headers, BYTE } } + if(window->uri && compare_ignoring_frag(window->uri, uri)) { + TRACE("fragment navigate\n"); + return navigate_fragment(window, uri); + } + hres = CreateURLMonikerEx2(NULL, uri, &mon, URL_MK_UNIFORM); if(FAILED(hres)) return hres; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 56fefa34ef6..5a1970d021c 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -130,7 +130,6 @@ typedef nsISupports nsIDOMMediaList; typedef nsISupports nsIDOMHTMLTableCaptionElement; typedef nsISupports nsIDOMHTMLTableSectionElement; typedef nsISupports nsIDOMClientRectList; -typedef nsISupports nsIDOMLocation; typedef nsISupports nsINode; typedef nsISupports nsIStyleSheet; typedef nsISupports nsIStyleRule; @@ -556,6 +555,35 @@ interface nsIChannelEventSink : nsISupports [ object, + uuid(a6cf906d-15b3-11d2-932e-00805f8add32), + local +] +interface nsIDOMLocation : nsISupports +{ + nsresult GetHash(nsAString *aHash); + nsresult SetHash(const nsAString *aHash); + nsresult GetHost(nsAString *aHost); + nsresult SetHost(const nsAString *aHost); + nsresult GetHostname(nsAString *aHostname); + nsresult SetHostname(const nsAString *aHostname); + nsresult GetHref(nsAString *aHref); + nsresult SetHref(const nsAString *aHref); + nsresult GetPathname(nsAString *aPathname); + nsresult SetPathname(const nsAString *aPathname); + nsresult GetPort(nsAString *aPort); + nsresult SetPort(const nsAString *aPort); + nsresult GetProtocol(nsAString *aProtocol); + nsresult SetProtocol(const nsAString *aProtocol); + nsresult GetSearch(nsAString *aSearch); + nsresult SetSearch(const nsAString *aSearch); + nsresult Reload(PRBool forceget); + nsresult Replace(const nsAString *url); + nsresult Assign(const nsAString *url); + nsresult ToString(nsAString *_retval); +} + +[ + object, uuid(2938307a-9d70-4b63-8afc-0197e82318ad), local ] diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index b39453e3fc4..b507446dd09 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -113,7 +113,7 @@ static IUri *get_uri_nofrag(IUri *uri) return ret; } -static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2) +BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2) { IUri *uri_nofrag1, *uri_nofrag2; BOOL ret = FALSE; diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index ad7f4a62f5d..4167659d997 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -70,7 +70,7 @@ static BOOL use_gecko_script(HTMLWindow *window) return FAILED(hres) || scheme != URL_SCHEME_ABOUT; } -static void set_current_uri(HTMLWindow *window, IUri *uri) +void set_current_uri(HTMLWindow *window, IUri *uri) { if(window->uri) { IUri_Release(window->uri); -- 2.11.4.GIT