[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