From: Alex Henrie Subject: [PATCH 3/3] mshtml: Add support for clicking image maps. Message-Id: <1438700455-23868-1-git-send-email-alexhenrie24@gmail.com> Date: Tue, 4 Aug 2015 09:00:55 -0600 Fixes https://bugs.winehq.org/show_bug.cgi?id=29468 --- dlls/mshtml/htmlanchor.c | 100 ++++++++++++++++++++++++++----------------- dlls/mshtml/htmlarea.c | 8 +++- dlls/mshtml/htmlevent.h | 34 --------------- dlls/mshtml/mshtml_private.h | 35 +++++++++++++++ 4 files changed, 102 insertions(+), 75 deletions(-) diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c index a52c049..c89a025 100644 --- a/dlls/mshtml/htmlanchor.c +++ b/dlls/mshtml/htmlanchor.c @@ -43,29 +43,35 @@ typedef struct { nsIDOMHTMLAnchorElement *nsanchor; } HTMLAnchorElement; -static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *target) +static HRESULT navigate_href_new_window(HTMLElement *element, nsIDOMHTMLAnchorElement *nsanchor, + nsIDOMHTMLAreaElement *nsarea, const WCHAR *target) { nsAString href_str; IUri *uri; nsresult nsres; HRESULT hres; + assert(!nsanchor ^ !nsarea); + nsAString_Init(&href_str, NULL); - nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); + if(nsanchor) + nsres = nsIDOMHTMLAnchorElement_GetHref(nsanchor, &href_str); + else + nsres = nsIDOMHTMLAreaElement_GetHref(nsarea, &href_str); if(NS_SUCCEEDED(nsres)) { const PRUnichar *href; nsAString_GetData(&href_str, &href); - hres = create_relative_uri(This->element.node.doc->basedoc.window, href, &uri); + hres = create_relative_uri(element->node.doc->basedoc.window, href, &uri); }else { - ERR("Could not get anchor href: %08x\n", nsres); + ERR("Could not get href: %08x\n", nsres); hres = E_FAIL; } nsAString_Finish(&href_str); if(FAILED(hres)) return hres; - hres = navigate_new_window(This->element.node.doc->basedoc.window, uri, target, NULL, NULL); + hres = navigate_new_window(element->node.doc->basedoc.window, uri, target, NULL, NULL); IUri_Release(uri); return hres; } @@ -119,7 +125,7 @@ HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_st return ret_window; } -static HRESULT navigate_anchor(HTMLAnchorElement *This) +static HRESULT navigate_href(HTMLElement *element, nsIDOMHTMLAnchorElement *nsanchor, nsIDOMHTMLAreaElement *nsarea) { nsAString href_str, target_str; HTMLOuterWindow *window; @@ -127,18 +133,22 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This) nsresult nsres; HRESULT hres = E_FAIL; + assert(!nsanchor ^ !nsarea); nsAString_Init(&target_str, NULL); - nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str); + if (nsanchor) + nsres = nsIDOMHTMLAnchorElement_GetTarget(nsanchor, &target_str); + else + nsres = nsIDOMHTMLAreaElement_GetTarget(nsarea, &target_str); if(NS_FAILED(nsres)) return E_FAIL; - window = get_target_window(This->element.node.doc->basedoc.window, &target_str, &use_new_window); + window = get_target_window(element->node.doc->basedoc.window, &target_str, &use_new_window); if(!window && use_new_window) { const PRUnichar *target; nsAString_GetData(&target_str, &target); - hres = navigate_anchor_window(This, target); + hres = navigate_href_new_window(element, nsanchor, nsarea, target); nsAString_Finish(&target_str); return hres; } @@ -148,7 +158,10 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This) return S_OK; nsAString_Init(&href_str, NULL); - nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); + if (nsanchor) + nsres = nsIDOMHTMLAnchorElement_GetHref(nsanchor, &href_str); + else + nsres = nsIDOMHTMLAreaElement_GetHref(nsarea, &href_str); if(NS_SUCCEEDED(nsres)) { const PRUnichar *href; @@ -165,6 +178,42 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This) return hres; } +HRESULT handle_link_events(HTMLElement *element, nsIDOMHTMLAnchorElement *nsanchor, nsIDOMHTMLAreaElement *nsarea, + eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default) +{ + assert(!nsanchor ^ !nsarea); + + if(eid == EVENTID_CLICK) { + nsIDOMMouseEvent *mouse_event; + INT16 button; + nsresult nsres; + + TRACE("CLICK\n"); + + nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event); + assert(nsres == NS_OK); + + nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button); + assert(nsres == NS_OK); + + nsIDOMMouseEvent_Release(mouse_event); + + switch(button) { + case 0: + *prevent_default = TRUE; + return navigate_href(element, nsanchor, nsarea); + case 1: + *prevent_default = TRUE; + return navigate_href_new_window(element, nsanchor, nsarea, NULL); + default: + *prevent_default = FALSE; + return S_OK; + } + } + + return HTMLElement_handle_event(&element->node, eid, event, prevent_default); +} + static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface) { return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface); @@ -721,36 +770,7 @@ static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default) { HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface); - - if(eid == EVENTID_CLICK) { - nsIDOMMouseEvent *mouse_event; - INT16 button; - nsresult nsres; - - TRACE("CLICK\n"); - - nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event); - assert(nsres == NS_OK); - - nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button); - assert(nsres == NS_OK); - - nsIDOMMouseEvent_Release(mouse_event); - - switch(button) { - case 0: - *prevent_default = TRUE; - return navigate_anchor(This); - case 1: - *prevent_default = TRUE; - return navigate_anchor_window(This, NULL); - default: - *prevent_default = FALSE; - return S_OK; - } - } - - return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default); + return handle_link_events(&This->element, This->nsanchor, NULL, eid, event, prevent_default); } static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) diff --git a/dlls/mshtml/htmlarea.c b/dlls/mshtml/htmlarea.c index 33a0468..7c76141 100644 --- a/dlls/mshtml/htmlarea.c +++ b/dlls/mshtml/htmlarea.c @@ -403,12 +403,18 @@ static HRESULT HTMLAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) return S_OK; } +static HRESULT HTMLAreaElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default) +{ + HTMLAreaElement *This = impl_from_HTMLDOMNode(iface); + return handle_link_events(&This->element, NULL, This->nsarea, eid, event, prevent_default); +} + static const NodeImplVtbl HTMLAreaElementImplVtbl = { HTMLAreaElement_QI, HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, - HTMLElement_handle_event, + HTMLAreaElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index fefc749..c92d50e 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -16,40 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -typedef enum { - EVENTID_ABORT, - EVENTID_BEFOREUNLOAD, - EVENTID_BLUR, - EVENTID_CHANGE, - EVENTID_CLICK, - EVENTID_CONTEXTMENU, - EVENTID_DATAAVAILABLE, - EVENTID_DBLCLICK, - EVENTID_DRAG, - EVENTID_DRAGSTART, - EVENTID_ERROR, - EVENTID_FOCUS, - EVENTID_FOCUSIN, - EVENTID_HELP, - EVENTID_KEYDOWN, - EVENTID_KEYPRESS, - EVENTID_KEYUP, - EVENTID_LOAD, - EVENTID_MOUSEDOWN, - EVENTID_MOUSEMOVE, - EVENTID_MOUSEOUT, - EVENTID_MOUSEOVER, - EVENTID_MOUSEUP, - EVENTID_MOUSEWHEEL, - EVENTID_PASTE, - EVENTID_READYSTATECHANGE, - EVENTID_RESIZE, - EVENTID_SCROLL, - EVENTID_SELECTSTART, - EVENTID_SUBMIT, - EVENTID_LAST -} eventid_t; - eventid_t str_to_eid(LPCWSTR) DECLSPEC_HIDDEN; void check_event_attr(HTMLDocumentNode*,nsIDOMHTMLElement*) DECLSPEC_HIDDEN; void release_event_target(event_target_t*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 43fa2a7..fd39713 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -303,6 +303,40 @@ typedef enum { dispex_prop_type_t get_dispid_type(DISPID) DECLSPEC_HIDDEN; +typedef enum { + EVENTID_ABORT, + EVENTID_BEFOREUNLOAD, + EVENTID_BLUR, + EVENTID_CHANGE, + EVENTID_CLICK, + EVENTID_CONTEXTMENU, + EVENTID_DATAAVAILABLE, + EVENTID_DBLCLICK, + EVENTID_DRAG, + EVENTID_DRAGSTART, + EVENTID_ERROR, + EVENTID_FOCUS, + EVENTID_FOCUSIN, + EVENTID_HELP, + EVENTID_KEYDOWN, + EVENTID_KEYPRESS, + EVENTID_KEYUP, + EVENTID_LOAD, + EVENTID_MOUSEDOWN, + EVENTID_MOUSEMOVE, + EVENTID_MOUSEOUT, + EVENTID_MOUSEOVER, + EVENTID_MOUSEUP, + EVENTID_MOUSEWHEEL, + EVENTID_PASTE, + EVENTID_READYSTATECHANGE, + EVENTID_RESIZE, + EVENTID_SCROLL, + EVENTID_SELECTSTART, + EVENTID_SUBMIT, + EVENTID_LAST +} eventid_t; + typedef struct HTMLWindow HTMLWindow; typedef struct HTMLInnerWindow HTMLInnerWindow; typedef struct HTMLOuterWindow HTMLOuterWindow; @@ -996,6 +1030,7 @@ HRESULT search_window_props(HTMLInnerWindow*,BSTR,DWORD,DISPID*) DECLSPEC_HIDDEN HRESULT get_frame_by_name(HTMLOuterWindow*,const WCHAR*,BOOL,HTMLOuterWindow**) DECLSPEC_HIDDEN; HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN; HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*) DECLSPEC_HIDDEN; +HRESULT handle_link_events(HTMLElement*,nsIDOMHTMLAnchorElement*,nsIDOMHTMLAreaElement*,eventid_t,nsIDOMEvent*,BOOL*) DECLSPEC_HIDDEN; HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN; -- 2.5.0