2008-07-08 16:39:29 +00:00
|
|
|
/*
|
2009-10-20 19:28:02 +00:00
|
|
|
* Copyright 2008-2009 Jacek Caban for CodeWeavers
|
2008-07-08 16:39:29 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mshtml_private.h"
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
typedef struct {
|
|
|
|
IDispatch *handler_prop;
|
|
|
|
DWORD handler_cnt;
|
|
|
|
IDispatch *handlers[0];
|
|
|
|
} handler_vector_t;
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
struct event_target_t {
|
2009-10-20 19:28:02 +00:00
|
|
|
handler_vector_t *event_table[EVENTID_LAST];
|
2008-07-08 16:39:29 +00:00
|
|
|
};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR abortW[] = {'a','b','o','r','t',0};
|
|
|
|
static const WCHAR onabortW[] = {'o','n','a','b','o','r','t',0};
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
static const WCHAR beforeunloadW[] = {'b','e','f','o','r','e','u','n','l','o','a','d',0};
|
|
|
|
static const WCHAR onbeforeunloadW[] = {'o','n','b','e','f','o','r','e','u','n','l','o','a','d',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR blurW[] = {'b','l','u','r',0};
|
|
|
|
static const WCHAR onblurW[] = {'o','n','b','l','u','r',0};
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
static const WCHAR changeW[] = {'c','h','a','n','g','e',0};
|
|
|
|
static const WCHAR onchangeW[] = {'o','n','c','h','a','n','g','e',0};
|
|
|
|
|
|
|
|
static const WCHAR clickW[] = {'c','l','i','c','k',0};
|
|
|
|
static const WCHAR onclickW[] = {'o','n','c','l','i','c','k',0};
|
|
|
|
|
2010-05-29 14:54:55 +00:00
|
|
|
static const WCHAR contextmenuW[] = {'c','o','n','t','e','x','t','m','e','n','u',0};
|
|
|
|
static const WCHAR oncontextmenuW[] = {'o','n','c','o','n','t','e','x','t','m','e','n','u',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR dataavailableW[] = {'d','a','t','a','a','v','a','i','l','a','b','l','e',0};
|
|
|
|
static const WCHAR ondataavailableW[] = {'o','n','d','a','t','a','a','v','a','i','l','a','b','l','e',0};
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
static const WCHAR dblclickW[] = {'d','b','l','c','l','i','c','k',0};
|
|
|
|
static const WCHAR ondblclickW[] = {'o','n','d','b','l','c','l','i','c','k',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR dragW[] = {'d','r','a','g',0};
|
|
|
|
static const WCHAR ondragW[] = {'o','n','d','r','a','g',0};
|
|
|
|
|
|
|
|
static const WCHAR dragstartW[] = {'d','r','a','g','s','t','a','r','t',0};
|
|
|
|
static const WCHAR ondragstartW[] = {'o','n','d','r','a','g','s','t','a','r','t',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR errorW[] = {'e','r','r','o','r',0};
|
|
|
|
static const WCHAR onerrorW[] = {'o','n','e','r','r','o','r',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR focusW[] = {'f','o','c','u','s',0};
|
|
|
|
static const WCHAR onfocusW[] = {'o','n','f','o','c','u','s',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR helpW[] = {'h','e','l','p',0};
|
|
|
|
static const WCHAR onhelpW[] = {'o','n','h','e','l','p',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR keydownW[] = {'k','e','y','d','o','w','n',0};
|
|
|
|
static const WCHAR onkeydownW[] = {'o','n','k','e','y','d','o','w','n',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR keypressW[] = {'k','e','y','p','r','e','s','s',0};
|
|
|
|
static const WCHAR onkeypressW[] = {'o','n','k','e','y','p','r','e','s','s',0};
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
static const WCHAR keyupW[] = {'k','e','y','u','p',0};
|
|
|
|
static const WCHAR onkeyupW[] = {'o','n','k','e','y','u','p',0};
|
|
|
|
|
|
|
|
static const WCHAR loadW[] = {'l','o','a','d',0};
|
|
|
|
static const WCHAR onloadW[] = {'o','n','l','o','a','d',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR mousedownW[] = {'m','o','u','s','e','d','o','w','n',0};
|
|
|
|
static const WCHAR onmousedownW[] = {'o','n','m','o','u','s','e','d','o','w','n',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR mousemoveW[] = {'m','o','u','s','e','m','o','v','e',0};
|
|
|
|
static const WCHAR onmousemoveW[] = {'o','n','m','o','u','s','e','m','o','v','e',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR mouseoutW[] = {'m','o','u','s','e','o','u','t',0};
|
|
|
|
static const WCHAR onmouseoutW[] = {'o','n','m','o','u','s','e','o','u','t',0};
|
|
|
|
|
|
|
|
static const WCHAR mouseoverW[] = {'m','o','u','s','e','o','v','e','r',0};
|
|
|
|
static const WCHAR onmouseoverW[] = {'o','n','m','o','u','s','e','o','v','e','r',0};
|
|
|
|
|
|
|
|
static const WCHAR mouseupW[] = {'m','o','u','s','e','u','p',0};
|
|
|
|
static const WCHAR onmouseupW[] = {'o','n','m','o','u','s','e','u','p',0};
|
|
|
|
|
2014-10-02 09:51:19 +00:00
|
|
|
static const WCHAR mousewheelW[] = {'m','o','u','s','e','w','h','e','e','l',0};
|
|
|
|
static const WCHAR onmousewheelW[] = {'o','n','m','o','u','s','e','w','h','e','e','l',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR pasteW[] = {'p','a','s','t','e',0};
|
|
|
|
static const WCHAR onpasteW[] = {'o','n','p','a','s','t','e',0};
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
|
|
|
|
static const WCHAR onreadystatechangeW[] = {'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
|
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
static const WCHAR resizeW[] = {'r','e','s','i','z','e',0};
|
|
|
|
static const WCHAR onresizeW[] = {'o','n','r','e','s','i','z','e',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR scrollW[] = {'s','c','r','o','l','l',0};
|
|
|
|
static const WCHAR onscrollW[] = {'o','n','s','c','r','o','l','l',0};
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const WCHAR selectstartW[] = {'s','e','l','e','c','t','s','t','a','r','t',0};
|
|
|
|
static const WCHAR onselectstartW[] = {'o','n','s','e','l','e','c','t','s','t','a','r','t',0};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static const WCHAR submitW[] = {'s','u','b','m','i','t',0};
|
|
|
|
static const WCHAR onsubmitW[] = {'o','n','s','u','b','m','i','t',0};
|
|
|
|
|
2009-11-15 23:44:20 +00:00
|
|
|
static const WCHAR HTMLEventsW[] = {'H','T','M','L','E','v','e','n','t','s',0};
|
|
|
|
static const WCHAR KeyboardEventW[] = {'K','e','y','b','o','a','r','d','E','v','e','n','t',0};
|
|
|
|
static const WCHAR MouseEventW[] = {'M','o','u','s','e','E','v','e','n','t',0};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
EVENTT_NONE,
|
|
|
|
EVENTT_HTML,
|
|
|
|
EVENTT_KEY,
|
|
|
|
EVENTT_MOUSE
|
|
|
|
};
|
|
|
|
|
|
|
|
static const WCHAR *event_types[] = {
|
|
|
|
NULL,
|
|
|
|
HTMLEventsW,
|
|
|
|
KeyboardEventW,
|
|
|
|
MouseEventW
|
|
|
|
};
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
typedef struct {
|
|
|
|
LPCWSTR name;
|
|
|
|
LPCWSTR attr_name;
|
2009-11-15 23:44:20 +00:00
|
|
|
DWORD type;
|
2010-01-18 16:27:14 +00:00
|
|
|
DISPID dispid;
|
2008-07-08 16:39:29 +00:00
|
|
|
DWORD flags;
|
|
|
|
} event_info_t;
|
|
|
|
|
|
|
|
#define EVENT_DEFAULTLISTENER 0x0001
|
2009-02-04 14:35:06 +00:00
|
|
|
#define EVENT_BUBBLE 0x0002
|
2009-10-20 19:28:02 +00:00
|
|
|
#define EVENT_FORWARDBODY 0x0004
|
2014-04-26 18:30:09 +00:00
|
|
|
#define EVENT_BIND_TO_BODY 0x0008
|
2013-05-19 21:21:20 +00:00
|
|
|
#define EVENT_CANCELABLE 0x0010
|
|
|
|
#define EVENT_HASDEFAULTHANDLERS 0x0020
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
static const event_info_t event_info[] = {
|
2013-05-19 21:21:20 +00:00
|
|
|
{abortW, onabortW, EVENTT_NONE, DISPID_EVMETH_ONABORT,
|
2014-04-26 18:30:09 +00:00
|
|
|
EVENT_BIND_TO_BODY},
|
2010-01-18 16:27:14 +00:00
|
|
|
{beforeunloadW, onbeforeunloadW, EVENTT_NONE, DISPID_EVMETH_ONBEFOREUNLOAD,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY},
|
|
|
|
{blurW, onblurW, EVENTT_HTML, DISPID_EVMETH_ONBLUR,
|
|
|
|
EVENT_DEFAULTLISTENER},
|
|
|
|
{changeW, onchangeW, EVENTT_HTML, DISPID_EVMETH_ONCHANGE,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
|
|
|
{clickW, onclickW, EVENTT_MOUSE, DISPID_EVMETH_ONCLICK,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE|EVENT_HASDEFAULTHANDLERS},
|
2010-05-29 14:54:55 +00:00
|
|
|
{contextmenuW, oncontextmenuW, EVENTT_MOUSE, DISPID_EVMETH_ONCONTEXTMENU,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_BUBBLE|EVENT_CANCELABLE},
|
|
|
|
{dataavailableW, ondataavailableW, EVENTT_NONE, DISPID_EVMETH_ONDATAAVAILABLE,
|
2010-05-29 14:54:55 +00:00
|
|
|
EVENT_BUBBLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{dblclickW, ondblclickW, EVENTT_MOUSE, DISPID_EVMETH_ONDBLCLICK,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{dragW, ondragW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAG,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_CANCELABLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{dragstartW, ondragstartW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAGSTART,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_CANCELABLE},
|
|
|
|
{errorW, onerrorW, EVENTT_NONE, DISPID_EVMETH_ONERROR,
|
2014-04-26 18:30:09 +00:00
|
|
|
EVENT_BIND_TO_BODY},
|
2010-01-18 16:27:14 +00:00
|
|
|
{focusW, onfocusW, EVENTT_HTML, DISPID_EVMETH_ONFOCUS,
|
|
|
|
EVENT_DEFAULTLISTENER},
|
2013-05-19 21:21:20 +00:00
|
|
|
{helpW, onhelpW, EVENTT_KEY, DISPID_EVMETH_ONHELP,
|
|
|
|
EVENT_BUBBLE|EVENT_CANCELABLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{keydownW, onkeydownW, EVENTT_KEY, DISPID_EVMETH_ONKEYDOWN,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_HASDEFAULTHANDLERS},
|
|
|
|
{keypressW, onkeypressW, EVENTT_KEY, DISPID_EVMETH_ONKEYPRESS,
|
2010-01-18 16:27:14 +00:00
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
|
|
|
{keyupW, onkeyupW, EVENTT_KEY, DISPID_EVMETH_ONKEYUP,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
|
|
|
{loadW, onloadW, EVENTT_HTML, DISPID_EVMETH_ONLOAD,
|
2014-04-26 18:30:09 +00:00
|
|
|
EVENT_BIND_TO_BODY},
|
2010-01-18 16:27:14 +00:00
|
|
|
{mousedownW, onmousedownW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEDOWN,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
2013-05-19 21:21:20 +00:00
|
|
|
{mousemoveW, onmousemoveW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEMOVE,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{mouseoutW, onmouseoutW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEOUT,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
|
|
|
{mouseoverW, onmouseoverW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEOVER,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
|
|
|
{mouseupW, onmouseupW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEUP,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
2014-10-02 09:51:19 +00:00
|
|
|
{mousewheelW, onmousewheelW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEWHEEL,
|
|
|
|
0},
|
2010-01-18 16:27:14 +00:00
|
|
|
{pasteW, onpasteW, EVENTT_NONE, DISPID_EVMETH_ONPASTE,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_CANCELABLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{readystatechangeW, onreadystatechangeW, EVENTT_NONE, DISPID_EVMETH_ONREADYSTATECHANGE,
|
|
|
|
0},
|
|
|
|
{resizeW, onresizeW, EVENTT_NONE, DISPID_EVMETH_ONRESIZE,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
2013-05-19 21:21:20 +00:00
|
|
|
{scrollW, onscrollW, EVENTT_HTML, DISPID_EVMETH_ONSCROLL,
|
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE},
|
2010-01-18 16:27:14 +00:00
|
|
|
{selectstartW, onselectstartW, EVENTT_MOUSE, DISPID_EVMETH_ONSELECTSTART,
|
2013-05-19 21:21:20 +00:00
|
|
|
EVENT_CANCELABLE},
|
|
|
|
{submitW, onsubmitW, EVENTT_HTML, DISPID_EVMETH_ONSUBMIT,
|
2014-10-02 09:51:19 +00:00
|
|
|
EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE|EVENT_HASDEFAULTHANDLERS}
|
2008-07-08 16:39:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
eventid_t str_to_eid(LPCWSTR str)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i=0; i < sizeof(event_info)/sizeof(event_info[0]); i++) {
|
|
|
|
if(!strcmpW(event_info[i].name, str))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
ERR("unknown type %s\n", debugstr_w(str));
|
|
|
|
return EVENTID_LAST;
|
|
|
|
}
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
static eventid_t attr_to_eid(LPCWSTR str)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i=0; i < sizeof(event_info)/sizeof(event_info[0]); i++) {
|
|
|
|
if(!strcmpW(event_info[i].attr_name, str))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EVENTID_LAST;
|
|
|
|
}
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
typedef struct {
|
2009-02-04 14:35:06 +00:00
|
|
|
DispatchEx dispex;
|
2013-05-19 21:21:20 +00:00
|
|
|
IHTMLEventObj IHTMLEventObj_iface;
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
LONG ref;
|
2009-02-04 14:35:06 +00:00
|
|
|
|
|
|
|
HTMLDOMNode *target;
|
2009-10-20 19:28:02 +00:00
|
|
|
const event_info_t *type;
|
|
|
|
nsIDOMEvent *nsevent;
|
2013-05-19 21:21:20 +00:00
|
|
|
BOOL prevent_default;
|
|
|
|
BOOL cancel_bubble;
|
2008-07-08 16:39:29 +00:00
|
|
|
} HTMLEventObj;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static inline HTMLEventObj *impl_from_IHTMLEventObj(IHTMLEventObj *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj_iface);
|
|
|
|
}
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_QueryInterface(IHTMLEventObj *iface, REFIID riid, void **ppv)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2014-10-02 09:51:19 +00:00
|
|
|
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
2013-05-19 21:21:20 +00:00
|
|
|
*ppv = &This->IHTMLEventObj_iface;
|
2008-07-08 16:39:29 +00:00
|
|
|
}else if(IsEqualGUID(&IID_IHTMLEventObj, riid)) {
|
2013-05-19 21:21:20 +00:00
|
|
|
*ppv = &This->IHTMLEventObj_iface;
|
2009-02-04 14:35:06 +00:00
|
|
|
}else if(dispex_query_interface(&This->dispex, riid, ppv)) {
|
|
|
|
return *ppv ? S_OK : E_NOINTERFACE;
|
2014-10-02 09:51:19 +00:00
|
|
|
}else {
|
|
|
|
*ppv = NULL;
|
|
|
|
WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
|
|
|
|
return E_NOINTERFACE;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2014-10-02 09:51:19 +00:00
|
|
|
IUnknown_AddRef((IUnknown*)*ppv);
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI HTMLEventObj_AddRef(IHTMLEventObj *iface)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2008-07-08 16:39:29 +00:00
|
|
|
LONG ref = InterlockedIncrement(&This->ref);
|
|
|
|
|
|
|
|
TRACE("(%p) ref=%d\n", This, ref);
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2008-07-08 16:39:29 +00:00
|
|
|
LONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
|
|
|
|
TRACE("(%p) ref=%d\n", This, ref);
|
|
|
|
|
2009-09-05 15:02:49 +00:00
|
|
|
if(!ref) {
|
2013-05-19 21:21:20 +00:00
|
|
|
if(This->target)
|
|
|
|
IHTMLDOMNode_Release(&This->target->IHTMLDOMNode_iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
if(This->nsevent)
|
|
|
|
nsIDOMEvent_Release(This->nsevent);
|
2009-09-05 15:02:49 +00:00
|
|
|
release_dispex(&This->dispex);
|
2008-07-08 16:39:29 +00:00
|
|
|
heap_free(This);
|
2009-09-05 15:02:49 +00:00
|
|
|
}
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_GetTypeInfoCount(IHTMLEventObj *iface, UINT *pctinfo)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_GetTypeInfo(IHTMLEventObj *iface, UINT iTInfo,
|
|
|
|
LCID lcid, ITypeInfo **ppTInfo)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID riid,
|
|
|
|
LPOLESTR *rgszNames, UINT cNames,
|
|
|
|
LCID lcid, DISPID *rgDispId)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
|
|
|
|
lcid, rgDispId);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMember,
|
|
|
|
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
|
|
|
|
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
|
2010-05-29 14:54:55 +00:00
|
|
|
wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLElement **p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-02-04 14:35:06 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
*p = NULL;
|
|
|
|
if(This->target)
|
|
|
|
IHTMLDOMNode_QueryInterface(&This->target->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
cpp_bool ret = FALSE;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMKeyEvent *key_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMKeyEvent_GetAltKey(key_event, &ret);
|
|
|
|
nsIDOMKeyEvent_Release(key_event);
|
|
|
|
}else {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetAltKey(mouse_event, &ret);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = ret ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
cpp_bool ret = FALSE;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMKeyEvent *key_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMKeyEvent_GetCtrlKey(key_event, &ret);
|
|
|
|
nsIDOMKeyEvent_Release(key_event);
|
|
|
|
}else {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetCtrlKey(mouse_event, &ret);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = ret ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
cpp_bool ret = FALSE;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMKeyEvent *key_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMKeyEvent_GetShiftKey(key_event, &ret);
|
|
|
|
nsIDOMKeyEvent_Release(key_event);
|
|
|
|
}else {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetShiftKey(mouse_event, &ret);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = ret ? VARIANT_TRUE : VARIANT_FALSE;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_put_returnValue(IHTMLEventObj *iface, VARIANT v)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
|
|
|
|
|
|
|
|
if(V_VT(&v) != VT_BOOL) {
|
|
|
|
FIXME("unsupported value %s\n", debugstr_variant(&v));
|
|
|
|
return DISP_E_BADVARTYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!V_BOOL(&v))
|
|
|
|
This->prevent_default = TRUE;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_returnValue(IHTMLEventObj *iface, VARIANT *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
V_VT(p) = VT_EMPTY;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_put_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL v)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
|
|
|
|
TRACE("(%p)->(%x)\n", This, v);
|
|
|
|
|
|
|
|
This->cancel_bubble = !!v;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
*p = This->cancel_bubble ? VARIANT_TRUE : VARIANT_FALSE;
|
2009-10-20 19:28:02 +00:00
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLElement **p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = NULL;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_toElement(IHTMLEventObj *iface, IHTMLElement **p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = NULL;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_put_keyCode(IHTMLEventObj *iface, LONG v)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-04-29 17:16:20 +00:00
|
|
|
FIXME("(%p)->(%d)\n", This, v);
|
2008-07-08 16:39:29 +00:00
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
UINT32 key_code = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMKeyEvent *key_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMKeyEvent_GetKeyCode(key_event, &key_code);
|
|
|
|
nsIDOMKeyEvent_Release(key_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = key_code;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_button(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
UINT16 button = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetButton(mouse_event, &button);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = button;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_type(IHTMLEventObj *iface, BSTR *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(!This->type) {
|
|
|
|
*p = NULL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
*p = SysAllocString(This->type->name);
|
|
|
|
return *p ? S_OK : E_OUTOFMEMORY;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_qualifier(IHTMLEventObj *iface, BSTR *p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = NULL;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_reason(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2014-04-26 18:30:09 +00:00
|
|
|
LONG x = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMUIEvent *ui_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
/* NOTE: pageX is not exactly right here. */
|
|
|
|
nsres = nsIDOMUIEvent_GetPageX(ui_event, &x);
|
|
|
|
assert(nsres == NS_OK);
|
|
|
|
nsIDOMUIEvent_Release(ui_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = x;
|
2009-10-20 19:28:02 +00:00
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2014-04-26 18:30:09 +00:00
|
|
|
LONG y = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMUIEvent *ui_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
/* NOTE: pageY is not exactly right here. */
|
|
|
|
nsres = nsIDOMUIEvent_GetPageY(ui_event, &y);
|
|
|
|
assert(nsres == NS_OK);
|
|
|
|
nsIDOMUIEvent_Release(ui_event);
|
|
|
|
}
|
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
*p = y;
|
2009-10-20 19:28:02 +00:00
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
LONG x = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetClientX(mouse_event, &x);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = x;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
LONG y = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetClientY(mouse_event, &y);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = y;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_offsetX(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_offsetY(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
LONG x = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetScreenX(mouse_event, &x);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = x;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-04-29 17:16:20 +00:00
|
|
|
static HRESULT WINAPI HTMLEventObj_get_screenY(IHTMLEventObj *iface, LONG *p)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
|
|
|
LONG y = 0;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
|
|
|
|
if(This->nsevent) {
|
|
|
|
nsIDOMMouseEvent *mouse_event;
|
|
|
|
nsresult nsres;
|
|
|
|
|
|
|
|
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
|
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
nsIDOMMouseEvent_GetScreenY(mouse_event, &y);
|
|
|
|
nsIDOMMouseEvent_Release(mouse_event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = y;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI HTMLEventObj_get_srcFilter(IHTMLEventObj *iface, IDispatch **p)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
FIXME("(%p)->(%p)\n", This, p);
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
*p = NULL;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const IHTMLEventObjVtbl HTMLEventObjVtbl = {
|
|
|
|
HTMLEventObj_QueryInterface,
|
|
|
|
HTMLEventObj_AddRef,
|
|
|
|
HTMLEventObj_Release,
|
|
|
|
HTMLEventObj_GetTypeInfoCount,
|
|
|
|
HTMLEventObj_GetTypeInfo,
|
|
|
|
HTMLEventObj_GetIDsOfNames,
|
|
|
|
HTMLEventObj_Invoke,
|
|
|
|
HTMLEventObj_get_srcElement,
|
|
|
|
HTMLEventObj_get_altKey,
|
|
|
|
HTMLEventObj_get_ctrlKey,
|
|
|
|
HTMLEventObj_get_shiftKey,
|
|
|
|
HTMLEventObj_put_returnValue,
|
|
|
|
HTMLEventObj_get_returnValue,
|
|
|
|
HTMLEventObj_put_cancelBubble,
|
|
|
|
HTMLEventObj_get_cancelBubble,
|
|
|
|
HTMLEventObj_get_fromElement,
|
|
|
|
HTMLEventObj_get_toElement,
|
|
|
|
HTMLEventObj_put_keyCode,
|
|
|
|
HTMLEventObj_get_keyCode,
|
|
|
|
HTMLEventObj_get_button,
|
|
|
|
HTMLEventObj_get_type,
|
|
|
|
HTMLEventObj_get_qualifier,
|
|
|
|
HTMLEventObj_get_reason,
|
|
|
|
HTMLEventObj_get_x,
|
|
|
|
HTMLEventObj_get_y,
|
|
|
|
HTMLEventObj_get_clientX,
|
|
|
|
HTMLEventObj_get_clientY,
|
|
|
|
HTMLEventObj_get_offsetX,
|
|
|
|
HTMLEventObj_get_offsetY,
|
|
|
|
HTMLEventObj_get_screenX,
|
|
|
|
HTMLEventObj_get_screenY,
|
|
|
|
HTMLEventObj_get_srcFilter
|
|
|
|
};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static inline HTMLEventObj *unsafe_impl_from_IHTMLEventObj(IHTMLEventObj *iface)
|
|
|
|
{
|
|
|
|
return iface->lpVtbl == &HTMLEventObjVtbl ? impl_from_IHTMLEventObj(iface) : NULL;
|
|
|
|
}
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
static const tid_t HTMLEventObj_iface_tids[] = {
|
|
|
|
IHTMLEventObj_tid,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
static dispex_static_data_t HTMLEventObj_dispex = {
|
|
|
|
NULL,
|
|
|
|
DispCEventObj_tid,
|
|
|
|
NULL,
|
|
|
|
HTMLEventObj_iface_tids
|
|
|
|
};
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static HTMLEventObj *create_event(void)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
|
|
|
HTMLEventObj *ret;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
ret = heap_alloc_zero(sizeof(*ret));
|
2009-11-15 23:44:20 +00:00
|
|
|
if(!ret)
|
|
|
|
return NULL;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
ret->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl;
|
2008-07-08 16:39:29 +00:00
|
|
|
ret->ref = 1;
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLEventObj_iface, &HTMLEventObj_dispex);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT set_event_info(HTMLEventObj *event, HTMLDOMNode *target, eventid_t eid, nsIDOMEvent *nsevent)
|
|
|
|
{
|
|
|
|
event->type = event_info+eid;
|
|
|
|
event->nsevent = nsevent;
|
|
|
|
|
2009-11-15 23:44:20 +00:00
|
|
|
if(nsevent) {
|
2009-10-20 19:28:02 +00:00
|
|
|
nsIDOMEvent_AddRef(nsevent);
|
2009-11-15 23:44:20 +00:00
|
|
|
}else if(event_types[event_info[eid].type]) {
|
2013-05-19 21:21:20 +00:00
|
|
|
nsAString type_str;
|
2009-11-15 23:44:20 +00:00
|
|
|
nsresult nsres;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
nsAString_InitDepend(&type_str, event_types[event_info[eid].type]);
|
|
|
|
nsres = nsIDOMHTMLDocument_CreateEvent(target->doc->nsdoc, &type_str, &event->nsevent);
|
|
|
|
nsAString_Finish(&type_str);
|
2009-11-15 23:44:20 +00:00
|
|
|
if(NS_FAILED(nsres)) {
|
|
|
|
ERR("Could not create event: %08x\n", nsres);
|
2013-05-19 21:21:20 +00:00
|
|
|
return E_FAIL;
|
2009-11-15 23:44:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
event->target = target;
|
|
|
|
if(target)
|
|
|
|
IHTMLDOMNode_AddRef(&target->IHTMLDOMNode_iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT create_event_obj(IHTMLEventObj **ret)
|
|
|
|
{
|
|
|
|
HTMLEventObj *event;
|
|
|
|
|
|
|
|
event = create_event();
|
|
|
|
if(!event)
|
|
|
|
return E_OUTOFMEMORY;
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
*ret = &event->IHTMLEventObj_iface;
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static HRESULT call_disp_func(IDispatch *disp, DISPPARAMS *dp, VARIANT *retv)
|
2010-01-18 16:27:14 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
IDispatchEx *dispex;
|
2010-01-18 16:27:14 +00:00
|
|
|
EXCEPINFO ei;
|
|
|
|
HRESULT hres;
|
|
|
|
|
|
|
|
memset(&ei, 0, sizeof(ei));
|
2013-05-19 21:21:20 +00:00
|
|
|
|
|
|
|
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
|
|
|
if(SUCCEEDED(hres)) {
|
|
|
|
hres = IDispatchEx_InvokeEx(dispex, 0, GetUserDefaultLCID(), DISPATCH_METHOD, dp, retv, &ei, NULL);
|
|
|
|
IDispatchEx_Release(dispex);
|
|
|
|
}else {
|
|
|
|
TRACE("Could not get IDispatchEx interface: %08x\n", hres);
|
|
|
|
hres = IDispatch_Invoke(disp, 0, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD,
|
|
|
|
dp, retv, &ei, NULL);
|
2010-01-18 16:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static HRESULT call_cp_func(IDispatch *disp, DISPID dispid, HTMLEventObj *event_obj, VARIANT *retv)
|
|
|
|
{
|
|
|
|
DISPPARAMS dp = {NULL,NULL,0,0};
|
|
|
|
VARIANT event_arg;
|
|
|
|
ULONG argerr;
|
|
|
|
EXCEPINFO ei;
|
|
|
|
|
|
|
|
if(event_obj) {
|
|
|
|
V_VT(&event_arg) = VT_DISPATCH;
|
|
|
|
V_DISPATCH(&event_arg) = (IDispatch*)&event_obj->IHTMLEventObj_iface;
|
|
|
|
dp.rgvarg = &event_arg;
|
|
|
|
dp.cArgs = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&ei, 0, sizeof(ei));
|
|
|
|
return IDispatch_Invoke(disp, dispid, &IID_NULL, 0, DISPATCH_METHOD, &dp, retv, &ei, &argerr);
|
|
|
|
}
|
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
static BOOL is_cp_event(cp_static_data_t *data, DISPID dispid)
|
|
|
|
{
|
|
|
|
int min, max, i;
|
|
|
|
HRESULT hres;
|
|
|
|
|
|
|
|
if(!data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if(!data->ids) {
|
|
|
|
hres = get_dispids(data->tid, &data->id_cnt, &data->ids);
|
|
|
|
if(FAILED(hres))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
min = 0;
|
|
|
|
max = data->id_cnt-1;
|
|
|
|
while(min <= max) {
|
|
|
|
i = (min+max)/2;
|
|
|
|
if(data->ids[i] == dispid)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if(data->ids[i] < dispid)
|
|
|
|
min = i+1;
|
|
|
|
else
|
|
|
|
max = i-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static void call_event_handlers(HTMLDocumentNode *doc, HTMLEventObj *event_obj, event_target_t *event_target,
|
2010-01-18 16:27:14 +00:00
|
|
|
ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj)
|
2009-10-20 19:28:02 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
const BOOL cancelable = event_info[eid].flags & EVENT_CANCELABLE;
|
2010-01-18 16:27:14 +00:00
|
|
|
handler_vector_t *handler_vector = NULL;
|
2013-05-19 21:21:20 +00:00
|
|
|
VARIANT v;
|
2009-10-20 19:28:02 +00:00
|
|
|
HRESULT hres;
|
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
if(event_target)
|
|
|
|
handler_vector = event_target->event_table[eid];
|
2009-10-20 19:28:02 +00:00
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
if(handler_vector && handler_vector->handler_prop) {
|
2009-10-20 19:28:02 +00:00
|
|
|
DISPID named_arg = DISPID_THIS;
|
|
|
|
VARIANTARG arg;
|
|
|
|
DISPPARAMS dp = {&arg, &named_arg, 1, 1};
|
|
|
|
|
|
|
|
V_VT(&arg) = VT_DISPATCH;
|
|
|
|
V_DISPATCH(&arg) = this_obj;
|
2013-05-19 21:21:20 +00:00
|
|
|
V_VT(&v) = VT_EMPTY;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
TRACE("%s >>>\n", debugstr_w(event_info[eid].name));
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = call_disp_func(handler_vector->handler_prop, &dp, &v);
|
|
|
|
if(hres == S_OK) {
|
|
|
|
TRACE("%s <<< %s\n", debugstr_w(event_info[eid].name), debugstr_variant(&v));
|
|
|
|
|
|
|
|
if(cancelable) {
|
|
|
|
if(V_VT(&v) == VT_BOOL) {
|
|
|
|
if(!V_BOOL(&v))
|
|
|
|
event_obj->prevent_default = TRUE;
|
|
|
|
}else if(V_VT(&v) != VT_EMPTY) {
|
|
|
|
FIXME("unhandled result %s\n", debugstr_variant(&v));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
}else {
|
2009-10-20 19:28:02 +00:00
|
|
|
WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres);
|
2013-05-19 21:21:20 +00:00
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
}
|
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
if(handler_vector && handler_vector->handler_cnt) {
|
2009-10-20 19:28:02 +00:00
|
|
|
VARIANTARG arg;
|
|
|
|
DISPPARAMS dp = {&arg, NULL, 1, 0};
|
2013-05-19 21:21:20 +00:00
|
|
|
int i;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
V_VT(&arg) = VT_DISPATCH;
|
|
|
|
V_DISPATCH(&arg) = (IDispatch*)event_obj;
|
|
|
|
|
2010-03-02 14:08:15 +00:00
|
|
|
i = handler_vector->handler_cnt;
|
|
|
|
while(i--) {
|
2009-10-20 19:28:02 +00:00
|
|
|
if(handler_vector->handlers[i]) {
|
2013-05-19 21:21:20 +00:00
|
|
|
V_VT(&v) = VT_EMPTY;
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i);
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = call_disp_func(handler_vector->handlers[i], &dp, &v);
|
|
|
|
if(hres == S_OK) {
|
2009-10-20 19:28:02 +00:00
|
|
|
TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i);
|
2013-05-19 21:21:20 +00:00
|
|
|
|
|
|
|
if(cancelable) {
|
|
|
|
if(V_VT(&v) == VT_BOOL) {
|
|
|
|
if(!V_BOOL(&v))
|
|
|
|
event_obj->prevent_default = TRUE;
|
|
|
|
}else if(V_VT(&v) != VT_EMPTY) {
|
|
|
|
FIXME("unhandled result %s\n", debugstr_variant(&v));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
}else {
|
2009-10-20 19:28:02 +00:00
|
|
|
WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres);
|
2013-05-19 21:21:20 +00:00
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-01-18 16:27:14 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
/*
|
|
|
|
* NOTE: CP events may require doc_obj reference, which we don't own. We make sure that
|
|
|
|
* it's safe to call event handler by checking nsevent_listener, which is NULL for
|
|
|
|
* detached documents.
|
|
|
|
*/
|
|
|
|
if(cp_container && cp_container->forward_container)
|
|
|
|
cp_container = cp_container->forward_container;
|
|
|
|
if(cp_container && cp_container->cps && doc->nsevent_listener) {
|
2010-01-18 16:27:14 +00:00
|
|
|
ConnectionPoint *cp;
|
2013-05-19 21:21:20 +00:00
|
|
|
unsigned i, j;
|
2010-01-18 16:27:14 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
for(j=0; cp_container->cp_entries[j].riid; j++) {
|
|
|
|
cp = cp_container->cps + j;
|
|
|
|
if(!cp->sinks_size || !is_cp_event(cp->data, event_info[eid].dispid))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for(i=0; doc->nsevent_listener && i < cp->sinks_size; i++) {
|
|
|
|
if(!cp->sinks[i].disp)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
V_VT(&v) = VT_EMPTY;
|
|
|
|
|
|
|
|
TRACE("cp %s [%u] >>>\n", debugstr_w(event_info[eid].name), i);
|
|
|
|
hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid,
|
|
|
|
cp->data->pass_event_arg ? event_obj : NULL, &v);
|
|
|
|
if(hres == S_OK) {
|
|
|
|
TRACE("cp %s [%u] <<<\n", debugstr_w(event_info[eid].name), i);
|
|
|
|
|
|
|
|
if(cancelable) {
|
|
|
|
if(V_VT(&v) == VT_BOOL) {
|
|
|
|
if(!V_BOOL(&v))
|
|
|
|
event_obj->prevent_default = TRUE;
|
|
|
|
}else if(V_VT(&v) != VT_EMPTY) {
|
|
|
|
FIXME("unhandled result %s\n", debugstr_variant(&v));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
}else {
|
|
|
|
WARN("cp %s [%u] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres);
|
2010-01-18 16:27:14 +00:00
|
|
|
}
|
|
|
|
}
|
2013-05-19 21:21:20 +00:00
|
|
|
|
|
|
|
if(!doc->nsevent_listener)
|
|
|
|
break;
|
2010-01-18 16:27:14 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *event_obj,
|
|
|
|
nsIDOMNode *target, IDispatch *script_this)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
IHTMLEventObj *prev_event;
|
2009-02-04 14:35:06 +00:00
|
|
|
nsIDOMNode *parent, *nsnode;
|
2013-05-19 21:21:20 +00:00
|
|
|
BOOL prevent_default = FALSE;
|
|
|
|
HTMLInnerWindow *window;
|
2008-07-08 16:39:29 +00:00
|
|
|
HTMLDOMNode *node;
|
2013-05-19 21:21:20 +00:00
|
|
|
UINT16 node_type;
|
|
|
|
nsresult nsres;
|
|
|
|
HRESULT hres;
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name));
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
window = doc->window;
|
|
|
|
if(!window) {
|
|
|
|
WARN("NULL window\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
htmldoc_addref(&doc->basedoc);
|
|
|
|
|
|
|
|
prev_event = window->event;
|
|
|
|
window->event = event_obj ? &event_obj->IHTMLEventObj_iface : NULL;
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
nsIDOMNode_GetNodeType(target, &node_type);
|
2009-02-04 14:35:06 +00:00
|
|
|
nsnode = target;
|
|
|
|
nsIDOMNode_AddRef(nsnode);
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
switch(node_type) {
|
|
|
|
case ELEMENT_NODE:
|
|
|
|
do {
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = get_node(doc, nsnode, FALSE, &node);
|
|
|
|
if(SUCCEEDED(hres) && node) {
|
|
|
|
call_event_handlers(doc, event_obj, *get_node_event_target(node),
|
|
|
|
node->cp_container, eid, script_this ? script_this : (IDispatch*)&node->IHTMLDOMNode_iface);
|
|
|
|
node_release(node);
|
|
|
|
}
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
|
2009-10-20 19:28:02 +00:00
|
|
|
break;
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
nsIDOMNode_GetParentNode(nsnode, &parent);
|
|
|
|
nsIDOMNode_Release(nsnode);
|
|
|
|
nsnode = parent;
|
|
|
|
if(!nsnode)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsIDOMNode_GetNodeType(nsnode, &node_type);
|
|
|
|
}while(node_type == ELEMENT_NODE);
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
|
2009-02-04 14:35:06 +00:00
|
|
|
break;
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
case DOCUMENT_NODE:
|
|
|
|
if(event_info[eid].flags & EVENT_FORWARDBODY) {
|
|
|
|
nsIDOMHTMLElement *nsbody;
|
|
|
|
nsresult nsres;
|
|
|
|
|
2009-11-15 23:44:20 +00:00
|
|
|
nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
|
2009-10-20 19:28:02 +00:00
|
|
|
if(NS_SUCCEEDED(nsres) && nsbody) {
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = get_node(doc, (nsIDOMNode*)nsbody, FALSE, &node);
|
|
|
|
if(SUCCEEDED(hres) && node) {
|
|
|
|
call_event_handlers(doc, event_obj, *get_node_event_target(node),
|
|
|
|
node->cp_container, eid, script_this ? script_this : (IDispatch*)&node->IHTMLDOMNode_iface);
|
|
|
|
node_release(node);
|
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
nsIDOMHTMLElement_Release(nsbody);
|
|
|
|
}else {
|
|
|
|
ERR("Could not get body: %08x\n", nsres);
|
|
|
|
}
|
|
|
|
}
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
call_event_handlers(doc, event_obj, doc->node.event_target, &doc->basedoc.cp_container, eid,
|
2013-05-19 21:21:20 +00:00
|
|
|
script_this ? script_this : (IDispatch*)&doc->basedoc.IHTMLDocument2_iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
FIXME("unimplemented node type %d\n", node_type);
|
2009-02-04 14:35:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(nsnode)
|
|
|
|
nsIDOMNode_Release(nsnode);
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(event_obj && event_obj->prevent_default)
|
|
|
|
prevent_default = TRUE;
|
|
|
|
window->event = prev_event;
|
|
|
|
|
|
|
|
if(!prevent_default && (event_info[eid].flags & EVENT_HASDEFAULTHANDLERS)) {
|
|
|
|
nsIDOMNode_AddRef(target);
|
|
|
|
nsnode = target;
|
|
|
|
|
|
|
|
do {
|
|
|
|
hres = get_node(doc, nsnode, TRUE, &node);
|
|
|
|
if(FAILED(hres))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if(node) {
|
|
|
|
if(node->vtbl->handle_event)
|
|
|
|
hres = node->vtbl->handle_event(node, eid, event_obj ? event_obj->nsevent : NULL, &prevent_default);
|
|
|
|
node_release(node);
|
|
|
|
if(FAILED(hres) || prevent_default || (event_obj && event_obj->cancel_bubble))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsres = nsIDOMNode_GetParentNode(nsnode, &parent);
|
|
|
|
if(NS_FAILED(nsres))
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsIDOMNode_Release(nsnode);
|
|
|
|
nsnode = parent;
|
|
|
|
} while(nsnode);
|
|
|
|
|
|
|
|
if(nsnode)
|
|
|
|
nsIDOMNode_Release(nsnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(prevent_default && event_obj && event_obj->nsevent) {
|
|
|
|
TRACE("calling PreventDefault\n");
|
|
|
|
nsIDOMEvent_PreventDefault(event_obj->nsevent);
|
|
|
|
}
|
|
|
|
|
|
|
|
htmldoc_release(&doc->basedoc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent,
|
|
|
|
IDispatch *script_this)
|
|
|
|
{
|
|
|
|
HTMLEventObj *event_obj = NULL;
|
|
|
|
HTMLDOMNode *node;
|
|
|
|
HRESULT hres;
|
|
|
|
|
|
|
|
if(set_event) {
|
|
|
|
hres = get_node(doc, target, TRUE, &node);
|
|
|
|
if(FAILED(hres))
|
|
|
|
return;
|
|
|
|
|
|
|
|
event_obj = create_event();
|
|
|
|
node_release(node);
|
|
|
|
if(!event_obj)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hres = set_event_info(event_obj, node, eid, nsevent);
|
|
|
|
if(FAILED(hres)) {
|
|
|
|
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fire_event_obj(doc, eid, event_obj, target, script_this);
|
|
|
|
|
2010-03-21 15:12:30 +00:00
|
|
|
if(event_obj)
|
2013-05-19 21:21:20 +00:00
|
|
|
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
|
2009-10-20 19:28:02 +00:00
|
|
|
}
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_var, VARIANT_BOOL *cancelled)
|
2009-11-15 23:44:20 +00:00
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
HTMLEventObj *event_obj = NULL;
|
2009-11-15 23:44:20 +00:00
|
|
|
eventid_t eid;
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT hres;
|
2009-11-15 23:44:20 +00:00
|
|
|
|
|
|
|
eid = attr_to_eid(event_name);
|
|
|
|
if(eid == EVENTID_LAST) {
|
|
|
|
WARN("unknown event %s\n", debugstr_w(event_name));
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(event_var && V_VT(event_var) != VT_EMPTY && V_VT(event_var) != VT_ERROR) {
|
|
|
|
if(V_VT(event_var) != VT_DISPATCH) {
|
|
|
|
FIXME("event_var %s not supported\n", debugstr_variant(event_var));
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
2009-11-15 23:44:20 +00:00
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(V_DISPATCH(event_var)) {
|
|
|
|
IHTMLEventObj *event_iface;
|
|
|
|
|
|
|
|
hres = IDispatch_QueryInterface(V_DISPATCH(event_var), &IID_IHTMLEventObj, (void**)&event_iface);
|
|
|
|
if(FAILED(hres)) {
|
|
|
|
FIXME("No IHTMLEventObj iface\n");
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
|
|
|
|
event_obj = unsafe_impl_from_IHTMLEventObj(event_iface);
|
|
|
|
if(!event_obj) {
|
|
|
|
ERR("Not our IHTMLEventObj?\n");
|
|
|
|
IHTMLEventObj_Release(event_iface);
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
}
|
2009-11-15 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(event_obj) {
|
|
|
|
hres = set_event_info(event_obj, node, eid, NULL);
|
|
|
|
if(SUCCEEDED(hres))
|
|
|
|
fire_event_obj(node->doc, eid, event_obj, node->nsnode, NULL);
|
|
|
|
|
|
|
|
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
|
|
|
|
if(FAILED(hres))
|
|
|
|
return hres;
|
|
|
|
}else {
|
|
|
|
if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER)) {
|
|
|
|
FIXME("not EVENT_DEFAULTEVENTHANDLER\n");
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fire_event(node->doc, eid, TRUE, node->nsnode, NULL, NULL);
|
|
|
|
}
|
2009-11-15 23:44:20 +00:00
|
|
|
|
|
|
|
*cancelled = VARIANT_TRUE; /* FIXME */
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT call_fire_event(HTMLDOMNode *node, eventid_t eid)
|
2009-11-15 23:44:20 +00:00
|
|
|
{
|
|
|
|
HRESULT hres;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
if(node->vtbl->fire_event) {
|
2009-11-15 23:44:20 +00:00
|
|
|
BOOL handled = FALSE;
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = node->vtbl->fire_event(node, eid, &handled);
|
2009-11-15 23:44:20 +00:00
|
|
|
if(handled)
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
fire_event(node->doc, eid, TRUE, node->nsnode, NULL, NULL);
|
2009-11-15 23:44:20 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
static inline event_target_t *get_event_target(event_target_t **event_target_ptr)
|
|
|
|
{
|
|
|
|
if(!*event_target_ptr)
|
|
|
|
*event_target_ptr = heap_alloc_zero(sizeof(event_target_t));
|
|
|
|
return *event_target_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, int cnt)
|
|
|
|
{
|
|
|
|
handler_vector_t *new_vector, *handler_vector = event_target->event_table[eid];
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
if(handler_vector) {
|
|
|
|
if(cnt <= handler_vector->handler_cnt)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
new_vector = heap_realloc_zero(handler_vector, sizeof(handler_vector_t) + sizeof(IDispatch*)*cnt);
|
|
|
|
}else {
|
|
|
|
new_vector = heap_alloc_zero(sizeof(handler_vector_t) + sizeof(IDispatch*)*cnt);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
2009-10-20 19:28:02 +00:00
|
|
|
|
|
|
|
if(!new_vector)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
new_vector->handler_cnt = cnt;
|
|
|
|
event_target->event_table[eid] = new_vector;
|
|
|
|
return TRUE;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, eventid_t eid)
|
2010-01-18 16:27:14 +00:00
|
|
|
{
|
2014-04-26 18:30:09 +00:00
|
|
|
nsIDOMNode *nsnode = NULL;
|
2010-03-21 15:12:30 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
TRACE("%s\n", debugstr_w(event_info[eid].name));
|
2010-03-21 15:12:30 +00:00
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
if(!doc->nsdoc || doc->event_vector[eid] || !(event_info[eid].flags & (EVENT_DEFAULTLISTENER|EVENT_BIND_TO_BODY)))
|
2010-03-21 15:12:30 +00:00
|
|
|
return S_OK;
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
if(event_info[eid].flags & EVENT_BIND_TO_BODY) {
|
2014-10-02 09:51:19 +00:00
|
|
|
nsnode = doc->node.nsnode;
|
|
|
|
nsIDOMNode_AddRef(nsnode);
|
2010-01-18 16:27:14 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
doc->event_vector[eid] = TRUE;
|
|
|
|
add_nsevent_listener(doc, nsnode, event_info[eid].name);
|
|
|
|
|
|
|
|
if(nsnode)
|
|
|
|
nsIDOMNode_Release(nsnode);
|
2010-01-18 16:27:14 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
void detach_events(HTMLDocumentNode *doc)
|
|
|
|
{
|
|
|
|
if(doc->event_vector) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i=0; i < EVENTID_LAST; i++) {
|
|
|
|
if(doc->event_vector[i]) {
|
|
|
|
detach_nsevent(doc, event_info[i].name);
|
|
|
|
doc->event_vector[i] = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
release_nsevents(doc);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-21 15:12:30 +00:00
|
|
|
static HRESULT remove_event_handler(event_target_t **event_target, eventid_t eid)
|
|
|
|
{
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
if(*event_target && (*event_target)->event_table[eid] && (*event_target)->event_table[eid]->handler_prop) {
|
2010-03-21 15:12:30 +00:00
|
|
|
IDispatch_Release((*event_target)->event_table[eid]->handler_prop);
|
|
|
|
(*event_target)->event_table[eid]->handler_prop = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc,
|
2009-11-15 23:44:20 +00:00
|
|
|
eventid_t eid, IDispatch *disp)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
2009-10-20 19:28:02 +00:00
|
|
|
event_target_t *event_target;
|
|
|
|
|
2010-03-21 15:12:30 +00:00
|
|
|
if(!disp)
|
|
|
|
return remove_event_handler(event_target_ptr, eid);
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
event_target = get_event_target(event_target_ptr);
|
|
|
|
if(!event_target)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
if(!alloc_handler_vector(event_target, eid, 0))
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
if(event_target->event_table[eid]->handler_prop)
|
|
|
|
IDispatch_Release(event_target->event_table[eid]->handler_prop);
|
2008-07-08 16:39:29 +00:00
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
event_target->event_table[eid]->handler_prop = disp;
|
2008-07-08 16:39:29 +00:00
|
|
|
IDispatch_AddRef(disp);
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
return ensure_nsevent_handler(doc, event_target, eid);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
|
|
|
switch(V_VT(var)) {
|
2009-02-04 14:35:06 +00:00
|
|
|
case VT_NULL:
|
2010-03-21 15:12:30 +00:00
|
|
|
return remove_event_handler(event_target, eid);
|
2009-02-04 14:35:06 +00:00
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
case VT_DISPATCH:
|
2014-04-26 18:30:09 +00:00
|
|
|
return set_event_handler_disp(event_target, doc, eid, V_DISPATCH(var));
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
default:
|
2013-05-19 21:21:20 +00:00
|
|
|
FIXME("not handler %s\n", debugstr_variant(var));
|
|
|
|
/* fall through */
|
2010-01-18 16:27:14 +00:00
|
|
|
case VT_EMPTY:
|
2009-02-04 14:35:06 +00:00
|
|
|
return E_NOTIMPL;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2009-02-04 14:35:06 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT get_event_handler(event_target_t **event_target, eventid_t eid, VARIANT *var)
|
|
|
|
{
|
2009-10-20 19:28:02 +00:00
|
|
|
if(*event_target && (*event_target)->event_table[eid] && (*event_target)->event_table[eid]->handler_prop) {
|
2009-02-04 14:35:06 +00:00
|
|
|
V_VT(var) = VT_DISPATCH;
|
2009-10-20 19:28:02 +00:00
|
|
|
V_DISPATCH(var) = (*event_target)->event_table[eid]->handler_prop;
|
2009-02-04 14:35:06 +00:00
|
|
|
IDispatch_AddRef(V_DISPATCH(var));
|
|
|
|
}else {
|
|
|
|
V_VT(var) = VT_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR name,
|
2010-03-21 15:12:30 +00:00
|
|
|
IDispatch *disp, VARIANT_BOOL *res)
|
2009-10-20 19:28:02 +00:00
|
|
|
{
|
|
|
|
event_target_t *event_target;
|
|
|
|
eventid_t eid;
|
|
|
|
DWORD i = 0;
|
|
|
|
|
|
|
|
eid = attr_to_eid(name);
|
|
|
|
if(eid == EVENTID_LAST) {
|
|
|
|
WARN("Unknown event\n");
|
|
|
|
*res = VARIANT_TRUE;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
event_target = get_event_target(event_target_ptr);
|
|
|
|
if(!event_target)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
if(event_target->event_table[eid]) {
|
|
|
|
while(i < event_target->event_table[eid]->handler_cnt && event_target->event_table[eid]->handlers[i])
|
|
|
|
i++;
|
|
|
|
if(i == event_target->event_table[eid]->handler_cnt && !alloc_handler_vector(event_target, eid, i+1))
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}else if(!alloc_handler_vector(event_target, eid, i+1)) {
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDispatch_AddRef(disp);
|
|
|
|
event_target->event_table[eid]->handlers[i] = disp;
|
|
|
|
|
|
|
|
*res = VARIANT_TRUE;
|
2014-04-26 18:30:09 +00:00
|
|
|
return ensure_nsevent_handler(doc->doc_node, event_target, eid);
|
2010-03-02 14:08:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name, IDispatch *disp)
|
|
|
|
{
|
|
|
|
eventid_t eid;
|
|
|
|
DWORD i = 0;
|
|
|
|
|
|
|
|
if(!event_target)
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
eid = attr_to_eid(name);
|
|
|
|
if(eid == EVENTID_LAST) {
|
|
|
|
WARN("Unknown event\n");
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!event_target->event_table[eid])
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
while(i < event_target->event_table[eid]->handler_cnt) {
|
|
|
|
if(event_target->event_table[eid]->handlers[i] == disp) {
|
|
|
|
IDispatch_Release(event_target->event_table[eid]->handlers[i]);
|
|
|
|
event_target->event_table[eid]->handlers[i] = NULL;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2009-10-20 19:28:02 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
void bind_node_event(HTMLDocumentNode *doc, event_target_t **event_target, HTMLDOMNode *node, const WCHAR *event, IDispatch *disp)
|
2013-05-19 21:21:20 +00:00
|
|
|
{
|
|
|
|
eventid_t eid;
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
TRACE("(%p %p %p %s %p)\n", doc, event_target, node, debugstr_w(event), disp);
|
2013-05-19 21:21:20 +00:00
|
|
|
|
|
|
|
eid = attr_to_eid(event);
|
|
|
|
if(eid == EVENTID_LAST) {
|
|
|
|
WARN("Unsupported event %s\n", debugstr_w(event));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
set_event_handler_disp(event_target, doc, eid, disp);
|
2013-05-19 21:21:20 +00:00
|
|
|
}
|
|
|
|
|
2014-04-26 18:30:09 +00:00
|
|
|
void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp)
|
2010-01-18 16:27:14 +00:00
|
|
|
{
|
2010-03-21 15:12:30 +00:00
|
|
|
event_target_t *event_target;
|
2010-01-18 16:27:14 +00:00
|
|
|
int i;
|
|
|
|
|
2010-03-21 15:12:30 +00:00
|
|
|
event_target = get_event_target(event_target_ptr);
|
|
|
|
if(!event_target)
|
|
|
|
return; /* FIXME */
|
|
|
|
|
2010-01-18 16:27:14 +00:00
|
|
|
for(i=0; i < EVENTID_LAST; i++) {
|
|
|
|
if((event_info[i].flags & EVENT_DEFAULTLISTENER) && is_cp_event(cp, event_info[i].dispid))
|
2014-04-26 18:30:09 +00:00
|
|
|
ensure_nsevent_handler(window->doc, event_target, i);
|
2010-01-18 16:27:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 09:51:19 +00:00
|
|
|
void check_event_attr(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem)
|
2008-07-08 16:39:29 +00:00
|
|
|
{
|
|
|
|
const PRUnichar *attr_value;
|
2014-10-02 09:51:19 +00:00
|
|
|
nsAString attr_value_str;
|
2008-07-08 16:39:29 +00:00
|
|
|
IDispatch *disp;
|
|
|
|
HTMLDOMNode *node;
|
|
|
|
int i;
|
|
|
|
nsresult nsres;
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT hres;
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
for(i=0; i < EVENTID_LAST; i++) {
|
2014-10-02 09:51:19 +00:00
|
|
|
nsres = get_elem_attr_value(nselem, event_info[i].attr_name, &attr_value_str, &attr_value);
|
2008-07-08 16:39:29 +00:00
|
|
|
if(NS_SUCCEEDED(nsres)) {
|
|
|
|
if(!*attr_value)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TRACE("%p.%s = %s\n", nselem, debugstr_w(event_info[i].attr_name), debugstr_w(attr_value));
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
disp = script_parse_event(doc->window, attr_value);
|
2008-07-08 16:39:29 +00:00
|
|
|
if(disp) {
|
2013-05-19 21:21:20 +00:00
|
|
|
hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
|
|
|
|
if(SUCCEEDED(hres)) {
|
2014-04-26 18:30:09 +00:00
|
|
|
set_event_handler_disp(get_node_event_target(node), node->doc, i, disp);
|
2013-05-19 21:21:20 +00:00
|
|
|
node_release(node);
|
|
|
|
}
|
2008-07-08 16:39:29 +00:00
|
|
|
IDispatch_Release(disp);
|
|
|
|
}
|
2014-10-02 09:51:19 +00:00
|
|
|
nsAString_Finish(&attr_value_str);
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-19 21:21:20 +00:00
|
|
|
HRESULT doc_init_events(HTMLDocumentNode *doc)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
HRESULT hres;
|
|
|
|
|
|
|
|
doc->event_vector = heap_alloc_zero(EVENTID_LAST*sizeof(BOOL));
|
|
|
|
if(!doc->event_vector)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
init_nsevents(doc);
|
|
|
|
|
|
|
|
for(i=0; i < EVENTID_LAST; i++) {
|
|
|
|
if(event_info[i].flags & EVENT_HASDEFAULTHANDLERS) {
|
2014-04-26 18:30:09 +00:00
|
|
|
hres = ensure_nsevent_handler(doc, NULL, i);
|
2013-05-19 21:21:20 +00:00
|
|
|
if(FAILED(hres))
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2008-07-08 16:39:29 +00:00
|
|
|
void release_event_target(event_target_t *event_target)
|
|
|
|
{
|
2013-05-19 21:21:20 +00:00
|
|
|
int i;
|
|
|
|
unsigned int j;
|
2008-07-08 16:39:29 +00:00
|
|
|
|
|
|
|
for(i=0; i < EVENTID_LAST; i++) {
|
2009-10-20 19:28:02 +00:00
|
|
|
if(event_target->event_table[i]) {
|
|
|
|
if(event_target->event_table[i]->handler_prop)
|
|
|
|
IDispatch_Release(event_target->event_table[i]->handler_prop);
|
|
|
|
for(j=0; j < event_target->event_table[i]->handler_cnt; j++)
|
2013-05-19 21:21:20 +00:00
|
|
|
if(event_target->event_table[i]->handlers[j])
|
|
|
|
IDispatch_Release(event_target->event_table[i]->handlers[j]);
|
2009-10-20 19:28:02 +00:00
|
|
|
}
|
2008-07-08 16:39:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
heap_free(event_target);
|
|
|
|
}
|