Module: wine Branch: master Commit: 3f2365d5decc3150db8dd797ba5527b561e24d5b URL: http://source.winehq.org/git/wine.git/?a=commit;h=3f2365d5decc3150db8dd797ba...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Sep 10 14:42:39 2012 +0200
mshtml: Added support for navigating to anchors with IDs containing '#'.
---
dlls/mshtml/navigate.c | 43 ++++++++++++++++++++++++++++++++++++++++--- dlls/mshtml/nsiface.idl | 11 +++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 91705dd..1046356 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 = NULL; + 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); + /* NOTE: Gecko doesn't set result to NULL if there is no match, so nselem must be initialized */ + nsres = nsIDOMNodeSelector_QuerySelector(node_selector, &selector_str, &nselem); + 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 ]