[PATCH 3/3] mshtml: Add support for clicking image maps.

Alex Henrie alexhenrie24 at gmail.com
Tue Aug 4 10:00:55 CDT 2015


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




More information about the wine-patches mailing list