On 09/10/12 12:19, Alexandre Julliard wrote:
> Jacek Caban <ja...@codeweavers.com> writes:
>
>> ---
>>  dlls/mshtml/navigate.c  |   42 +++++++++++++++++++++++++++++++++++++++---
>>  dlls/mshtml/nsiface.idl |   11 +++++++++++
>>  2 files changed, 50 insertions(+), 3 deletions(-)
> It doesn't work here:
>
> ../../../tools/runtest -q -P wine -M mshtml.dll -T ../../.. -p 
> mshtml_test.exe.so htmldoc.c && touch htmldoc.ok
> htmldoc.c:4650: Test failed: unexpected riid 
> {5C8B21BC-EF6E-4599-A26F-FACC05B4ADBE}
> make: *** [htmldoc.ok] Error 1

This looks like a bug in Gecko that doesn't set result to NULL when an
element is not found. Could you please confirm it with attached patch
(I'm interested in the error trace I've added).

Thanks,
Jacek
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index 91705dd..efd5a96 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -19,6 +19,7 @@
 #include "config.h"
 
 #include <stdarg.h>
+#include <assert.h>
 
 #define COBJMACROS
 #define NONAMELESSUNION
@@ -1925,10 +1926,13 @@ static HRESULT navigate_fragment(HTMLOuterWindow 
*window, IUri *uri)
 {
     nsIDOMLocation *nslocation;
     nsAString nsfrag_str;
+    WCHAR *selector;
     BSTR frag;
     nsresult nsres;
     HRESULT hres;
 
+    const WCHAR selector_formatW[] = 
{'a','[','i','d','=','"','%','s','"',']',0};
+
     set_current_uri(window, uri);
 
     nsres = nsIDOMWindow_GetLocation(window->nswindow, &nslocation);
@@ -1945,12 +1949,45 @@ static HRESULT navigate_fragment(HTMLOuterWindow 
*window, IUri *uri)
     nsres = nsIDOMLocation_SetHash(nslocation, &nsfrag_str);
     nsAString_Finish(&nsfrag_str);
     nsIDOMLocation_Release(nslocation);
-    SysFreeString(frag);
-    if(NS_FAILED(nsres)) {
+    if(NS_FAILED(nsres))
         ERR("SetHash failed: %08x\n", nsres);
-        return E_FAIL;
+
+    /*
+     * IE supports scrolling to anchor elements with "#hash" ids (note that 
'#' is part of the id),
+     * while Gecko scrolls only to elements with "hash" ids. We scroll the 
page ourselves if
+     * a[id="#hash"] element can be found.
+     */
+    selector = 
heap_alloc(sizeof(selector_formatW)+SysStringLen(frag)*sizeof(WCHAR));
+    if(selector) {
+        nsIDOMNodeSelector *node_selector;
+        nsIDOMElement *nselem = (void*)0xdeadbeef;
+        nsAString selector_str;
+
+        nsres = 
nsIDOMHTMLDocument_QueryInterface(window->base.inner_window->doc->nsdoc, 
&IID_nsIDOMNodeSelector,
+                (void**)&node_selector);
+        assert(nsres == NS_OK);
+
+        sprintfW(selector, selector_formatW, frag);
+        nsAString_InitDepend(&selector_str, selector);
+        nsres = nsIDOMNodeSelector_QuerySelector(node_selector, &selector_str, 
&nselem);
+        ERR("nselem %p %08x\n", nselem, nsres);
+        nsIDOMNodeSelector_Release(node_selector);
+        nsAString_Finish(&selector_str);
+        heap_free(selector);
+        if(NS_SUCCEEDED(nsres) && nselem) {
+            nsIDOMHTMLElement *html_elem;
+
+            nsres = nsIDOMElement_QueryInterface(nselem, 
&IID_nsIDOMHTMLElement, (void**)&html_elem);
+            nsIDOMElement_Release(nselem);
+            if(NS_SUCCEEDED(nsres)) {
+                nsIDOMHTMLElement_ScrollIntoView(html_elem, TRUE, 1);
+                nsIDOMHTMLElement_Release(html_elem);
+            }
+        }
     }
 
+    SysFreeString(frag);
+
     if(window->doc_obj->doc_object_service) {
         
IDocObjectService_FireNavigateComplete2(window->doc_obj->doc_object_service, 
&window->base.IHTMLWindow2_iface, 0x10);
         
IDocObjectService_FireDocumentComplete(window->doc_obj->doc_object_service, 
&window->base.IHTMLWindow2_iface, 0);
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index d19d5df..a4202f0 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -2073,6 +2073,17 @@ interface nsIDOMHTMLStyleElement : nsIDOMHTMLElement
 
 [
     object,
+    uuid(7cebc153-168a-416c-ba5a-56a8c2ddb2ec),
+    local
+]
+interface nsIDOMNodeSelector : nsISupports
+{
+    nsresult QuerySelector(const nsAString *selectors, nsIDOMElement 
**_retval);
+    nsresult QuerySelectorAll(const nsAString *selectors, nsIDOMNodeList 
**_retval);
+}
+
+[
+    object,
     uuid(94928ab3-8b63-11d3-989d-001083010e9b),
     local
 ]


Reply via email to