Jacek Caban : mshtml: Properly handle fragment-only navigation.

Alexandre Julliard julliard at winehq.org
Tue Nov 15 13:17:33 CST 2011


Module: wine
Branch: master
Commit: fbdfec74b04ee4fd627892102da026f90aba9d04
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fbdfec74b04ee4fd627892102da026f90aba9d04

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Nov 15 13:30:28 2011 +0100

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 0915977..625fc52 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 ea1c650..bb97ee1 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 56fefa3..5a1970d 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 b39453e..b507446 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 ad7f4a6..4167659 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);




More information about the wine-cvs mailing list