mshtml: Use the same click event handler for anchor and area elements.
This commit is contained in:
parent
36a39cea90
commit
0c986f98ad
@ -43,29 +43,18 @@ typedef struct {
|
|||||||
nsIDOMHTMLAnchorElement *nsanchor;
|
nsIDOMHTMLAnchorElement *nsanchor;
|
||||||
} HTMLAnchorElement;
|
} HTMLAnchorElement;
|
||||||
|
|
||||||
static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *target)
|
static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_str, const WCHAR *target)
|
||||||
{
|
{
|
||||||
nsAString href_str;
|
const PRUnichar *href;
|
||||||
IUri *uri;
|
IUri *uri;
|
||||||
nsresult nsres;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
nsAString_Init(&href_str, NULL);
|
nsAString_GetData(href_str, &href);
|
||||||
nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
|
hres = create_relative_uri(element->node.doc->basedoc.window, href, &uri);
|
||||||
if(NS_SUCCEEDED(nsres)) {
|
|
||||||
const PRUnichar *href;
|
|
||||||
|
|
||||||
nsAString_GetData(&href_str, &href);
|
|
||||||
hres = create_relative_uri(This->element.node.doc->basedoc.window, href, &uri);
|
|
||||||
}else {
|
|
||||||
ERR("Could not get anchor href: %08x\n", nsres);
|
|
||||||
hres = E_FAIL;
|
|
||||||
}
|
|
||||||
nsAString_Finish(&href_str);
|
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return 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);
|
IUri_Release(uri);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
@ -119,52 +108,72 @@ HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_st
|
|||||||
return ret_window;
|
return ret_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT navigate_anchor(HTMLAnchorElement *This)
|
static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str)
|
||||||
{
|
{
|
||||||
nsAString href_str, target_str;
|
|
||||||
HTMLOuterWindow *window;
|
HTMLOuterWindow *window;
|
||||||
BOOL use_new_window;
|
BOOL use_new_window;
|
||||||
nsresult nsres;
|
const PRUnichar *href;
|
||||||
HRESULT hres = E_FAIL;
|
HRESULT hres;
|
||||||
|
|
||||||
|
window = get_target_window(element->node.doc->basedoc.window, target_str, &use_new_window);
|
||||||
nsAString_Init(&target_str, NULL);
|
if(!window) {
|
||||||
nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
|
if(use_new_window) {
|
||||||
if(NS_FAILED(nsres))
|
const PRUnichar *target;
|
||||||
return E_FAIL;
|
nsAString_GetData(target_str, &target);
|
||||||
|
return navigate_href_new_window(element, href_str, target);
|
||||||
window = get_target_window(This->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);
|
|
||||||
nsAString_Finish(&target_str);
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAString_Finish(&target_str);
|
|
||||||
if(!window)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
nsAString_Init(&href_str, NULL);
|
|
||||||
nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
|
|
||||||
if(NS_SUCCEEDED(nsres)) {
|
|
||||||
const PRUnichar *href;
|
|
||||||
|
|
||||||
nsAString_GetData(&href_str, &href);
|
|
||||||
if(*href) {
|
|
||||||
hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
|
|
||||||
}else {
|
}else {
|
||||||
TRACE("empty href\n");
|
return S_OK;
|
||||||
hres = S_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nsAString_Finish(&href_str);
|
|
||||||
|
nsAString_GetData(href_str, &href);
|
||||||
|
if(*href) {
|
||||||
|
hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
|
||||||
|
}else {
|
||||||
|
TRACE("empty href\n");
|
||||||
|
hres = S_OK;
|
||||||
|
}
|
||||||
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str,
|
||||||
|
nsIDOMEvent *event, BOOL *prevent_default)
|
||||||
|
{
|
||||||
|
nsIDOMMouseEvent *mouse_event;
|
||||||
|
INT16 button;
|
||||||
|
nsresult nsres;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
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;
|
||||||
|
hres = navigate_href(element, href_str, target_str);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*prevent_default = TRUE;
|
||||||
|
hres = navigate_href_new_window(element, href_str, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*prevent_default = FALSE;
|
||||||
|
hres = S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAString_Finish(href_str);
|
||||||
|
nsAString_Finish(target_str);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
|
static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
|
return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
|
||||||
@ -721,33 +730,29 @@ 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)
|
static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default)
|
||||||
{
|
{
|
||||||
HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
|
HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
|
||||||
|
nsAString href_str, target_str;
|
||||||
|
nsresult nsres;
|
||||||
|
|
||||||
if(eid == EVENTID_CLICK) {
|
if(eid == EVENTID_CLICK) {
|
||||||
nsIDOMMouseEvent *mouse_event;
|
nsAString_Init(&href_str, NULL);
|
||||||
INT16 button;
|
nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
|
||||||
nsresult nsres;
|
if (NS_FAILED(nsres)) {
|
||||||
|
ERR("Could not get anchor href: %08x\n", nsres);
|
||||||
TRACE("CLICK\n");
|
goto fallback;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsAString_Init(&target_str, NULL);
|
||||||
|
nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
|
||||||
|
if (NS_FAILED(nsres)) {
|
||||||
|
ERR("Could not get anchor target: %08x\n", nsres);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
nsAString_Finish(&href_str);
|
||||||
|
nsAString_Finish(&target_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
|
return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
|
||||||
|
@ -403,12 +403,43 @@ static HRESULT HTMLAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT HTMLAreaElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default)
|
||||||
|
{
|
||||||
|
HTMLAreaElement *This = impl_from_HTMLDOMNode(iface);
|
||||||
|
nsAString href_str, target_str;
|
||||||
|
nsresult nsres;
|
||||||
|
|
||||||
|
if(eid == EVENTID_CLICK) {
|
||||||
|
nsAString_Init(&href_str, NULL);
|
||||||
|
nsres = nsIDOMHTMLAreaElement_GetHref(This->nsarea, &href_str);
|
||||||
|
if (NS_FAILED(nsres)) {
|
||||||
|
ERR("Could not get area href: %08x\n", nsres);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAString_Init(&target_str, NULL);
|
||||||
|
nsres = nsIDOMHTMLAreaElement_GetTarget(This->nsarea, &target_str);
|
||||||
|
if (NS_FAILED(nsres)) {
|
||||||
|
ERR("Could not get area target: %08x\n", nsres);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
nsAString_Finish(&href_str);
|
||||||
|
nsAString_Finish(&target_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
|
||||||
|
}
|
||||||
|
|
||||||
static const NodeImplVtbl HTMLAreaElementImplVtbl = {
|
static const NodeImplVtbl HTMLAreaElementImplVtbl = {
|
||||||
HTMLAreaElement_QI,
|
HTMLAreaElement_QI,
|
||||||
HTMLElement_destructor,
|
HTMLElement_destructor,
|
||||||
HTMLElement_cpc,
|
HTMLElement_cpc,
|
||||||
HTMLElement_clone,
|
HTMLElement_clone,
|
||||||
HTMLElement_handle_event,
|
HTMLAreaElement_handle_event,
|
||||||
HTMLElement_get_attr_col
|
HTMLElement_get_attr_col
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -996,6 +996,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_frame_by_name(HTMLOuterWindow*,const WCHAR*,BOOL,HTMLOuterWindow**) DECLSPEC_HIDDEN;
|
||||||
HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN;
|
HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN;
|
||||||
HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*) DECLSPEC_HIDDEN;
|
HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT handle_link_click_event(HTMLElement*,nsAString*,nsAString*,nsIDOMEvent*,BOOL*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN;
|
HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user