Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
d84f6f72
Commit
d84f6f72
authored
Nov 24, 2017
by
Jacek Caban
Committed by
Alexandre Julliard
Nov 24, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mshtml: Hook addEventListener InvokeEx calls to allow capture default value.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5bc2e83c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
76 additions
and
20 deletions
+76
-20
dispex.c
dlls/mshtml/dispex.c
+23
-10
htmlelem.c
dlls/mshtml/htmlelem.c
+5
-2
htmlevent.c
dlls/mshtml/htmlevent.c
+32
-1
mshtml_private.h
dlls/mshtml/mshtml_private.h
+9
-1
events.js
dlls/mshtml/tests/events.js
+7
-6
No files found.
dlls/mshtml/dispex.c
View file @
d84f6f72
...
...
@@ -52,6 +52,7 @@ typedef struct {
DISPID
id
;
BSTR
name
;
tid_t
tid
;
dispex_hook_invoke_t
hook
;
SHORT
call_vtbl_off
;
SHORT
put_vtbl_off
;
SHORT
get_vtbl_off
;
...
...
@@ -230,7 +231,8 @@ static BOOL is_arg_type_supported(VARTYPE vt)
return
FALSE
;
}
static
void
add_func_info
(
dispex_data_t
*
data
,
tid_t
tid
,
const
FUNCDESC
*
desc
,
ITypeInfo
*
dti
)
static
void
add_func_info
(
dispex_data_t
*
data
,
tid_t
tid
,
const
FUNCDESC
*
desc
,
ITypeInfo
*
dti
,
dispex_hook_invoke_t
hook
)
{
func_info_t
*
info
;
BSTR
name
;
...
...
@@ -262,6 +264,7 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
info
->
tid
=
tid
;
info
->
func_disp_idx
=
-
1
;
info
->
prop_vt
=
VT_EMPTY
;
info
->
hook
=
hook
;
}
else
{
SysFreeString
(
name
);
}
...
...
@@ -326,10 +329,9 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
}
}
static
HRESULT
process_interface
(
dispex_data_t
*
data
,
tid_t
tid
,
ITypeInfo
*
disp_typeinfo
,
const
DISPID
*
blacklist_dispid
s
)
static
HRESULT
process_interface
(
dispex_data_t
*
data
,
tid_t
tid
,
ITypeInfo
*
disp_typeinfo
,
const
dispex_hook_t
*
hook
s
)
{
unsigned
i
=
7
;
/* skip IDispatch functions */
const
DISPID
*
blacklist_iter
;
ITypeInfo
*
typeinfo
;
FUNCDESC
*
funcdesc
;
HRESULT
hres
;
...
...
@@ -339,20 +341,25 @@ static HRESULT process_interface(dispex_data_t *data, tid_t tid, ITypeInfo *disp
return
hres
;
while
(
1
)
{
const
dispex_hook_t
*
hook
=
NULL
;
hres
=
ITypeInfo_GetFuncDesc
(
typeinfo
,
i
++
,
&
funcdesc
);
if
(
FAILED
(
hres
))
break
;
if
(
blacklist_dispid
s
)
{
for
(
blacklist_iter
=
blacklist_dispids
;
*
blacklist_iter
!=
DISPID_UNKNOWN
;
blacklist_iter
++
)
{
if
(
*
blacklist_iter
==
funcdesc
->
memid
)
if
(
hook
s
)
{
for
(
hook
=
hooks
;
hook
->
dispid
!=
DISPID_UNKNOWN
;
hook
++
)
{
if
(
hook
->
dispid
==
funcdesc
->
memid
)
break
;
}
if
(
hook
->
dispid
==
DISPID_UNKNOWN
)
hook
=
NULL
;
}
if
(
!
blacklist_dispids
||
*
blacklist_iter
==
DISPID_UNKNOWN
)
{
if
(
!
hook
||
hook
->
invoke
)
{
TRACE
(
"adding...
\n
"
);
add_func_info
(
data
,
tid
,
funcdesc
,
disp_typeinfo
?
disp_typeinfo
:
typeinfo
);
add_func_info
(
data
,
tid
,
funcdesc
,
disp_typeinfo
?
disp_typeinfo
:
typeinfo
,
hook
?
hook
->
invoke
:
NULL
);
}
ITypeInfo_ReleaseFuncDesc
(
typeinfo
,
funcdesc
);
...
...
@@ -361,11 +368,11 @@ static HRESULT process_interface(dispex_data_t *data, tid_t tid, ITypeInfo *disp
return
S_OK
;
}
void
dispex_info_add_interface
(
dispex_data_t
*
info
,
tid_t
tid
,
const
DISPID
*
blacklist_dispid
s
)
void
dispex_info_add_interface
(
dispex_data_t
*
info
,
tid_t
tid
,
const
dispex_hook_t
*
hook
s
)
{
HRESULT
hres
;
hres
=
process_interface
(
info
,
tid
,
NULL
,
blacklist_dispid
s
);
hres
=
process_interface
(
info
,
tid
,
NULL
,
hook
s
);
if
(
FAILED
(
hres
))
ERR
(
"process_interface failed: %08x
\n
"
,
hres
);
}
...
...
@@ -1239,6 +1246,12 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
if
(
FAILED
(
hres
))
return
hres
;
if
(
func
->
hook
)
{
hres
=
func
->
hook
(
This
,
lcid
,
flags
,
dp
,
res
,
ei
,
caller
);
if
(
hres
!=
S_FALSE
)
return
hres
;
}
if
(
func
->
func_disp_idx
!=
-
1
)
return
function_invoke
(
This
,
func
,
flags
,
dp
,
res
,
ei
,
caller
);
...
...
dlls/mshtml/htmlelem.c
View file @
d84f6f72
...
...
@@ -5398,11 +5398,14 @@ static IHTMLEventObj *HTMLElement_set_current_event(DispatchEx *dispex, IHTMLEve
void
HTMLElement_init_dispex_info
(
dispex_data_t
*
info
,
compat_mode_t
mode
)
{
static
const
DISPID
elem2_ie11_blacklist
[]
=
{
DISPID_IHTMLELEMENT2_DOSCROLL
,
DISPID_UNKNOWN
};
static
const
dispex_hook_t
elem2_ie11_hooks
[]
=
{
{
DISPID_IHTMLELEMENT2_DOSCROLL
,
NULL
},
{
DISPID_UNKNOWN
}
};
HTMLDOMNode_init_dispex_info
(
info
,
mode
);
dispex_info_add_interface
(
info
,
IHTMLElement2_tid
,
mode
>=
COMPAT_MODE_IE11
?
elem2_ie11_
blacklist
:
NULL
);
dispex_info_add_interface
(
info
,
IHTMLElement2_tid
,
mode
>=
COMPAT_MODE_IE11
?
elem2_ie11_
hooks
:
NULL
);
if
(
mode
>=
COMPAT_MODE_IE8
)
dispex_info_add_interface
(
info
,
IElementSelector_tid
,
NULL
);
...
...
dlls/mshtml/htmlevent.c
View file @
d84f6f72
...
...
@@ -2051,6 +2051,11 @@ static inline EventTarget *impl_from_IEventTarget(IEventTarget *iface)
return
CONTAINING_RECORD
(
iface
,
EventTarget
,
IEventTarget_iface
);
}
static
inline
EventTarget
*
impl_from_DispatchEx
(
DispatchEx
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
EventTarget
,
dispex
);
}
static
HRESULT
WINAPI
EventTarget_QueryInterface
(
IEventTarget
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
EventTarget
*
This
=
impl_from_IEventTarget
(
iface
);
...
...
@@ -2162,6 +2167,27 @@ static HRESULT WINAPI EventTarget_dispatchEvent(IEventTarget *iface, IDOMEvent *
return
E_NOTIMPL
;
}
HRESULT
IEventTarget_addEventListener_hook
(
DispatchEx
*
dispex
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
res
,
EXCEPINFO
*
ei
,
IServiceProvider
*
caller
)
{
/* If only two arguments were given, implicitly set capture to false */
if
((
flags
&
DISPATCH_METHOD
)
&&
dp
->
cArgs
==
2
&&
!
dp
->
cNamedArgs
)
{
VARIANT
args
[
3
];
DISPPARAMS
new_dp
=
{
args
,
NULL
,
3
,
0
};
V_VT
(
args
)
=
VT_BOOL
;
V_BOOL
(
args
)
=
VARIANT_FALSE
;
args
[
1
]
=
dp
->
rgvarg
[
0
];
args
[
2
]
=
dp
->
rgvarg
[
1
];
TRACE
(
"implicit capture
\n
"
);
return
IDispatchEx_InvokeEx
(
&
dispex
->
IDispatchEx_iface
,
DISPID_IEVENTTARGET_ADDEVENTLISTENER
,
lcid
,
flags
,
&
new_dp
,
res
,
ei
,
caller
);
}
return
S_FALSE
;
/* fallback to default */
}
static
const
IEventTargetVtbl
EventTargetVtbl
=
{
EventTarget_QueryInterface
,
EventTarget_AddRef
,
...
...
@@ -2210,8 +2236,13 @@ HRESULT EventTarget_QI(EventTarget *event_target, REFIID riid, void **ppv)
void
EventTarget_init_dispex_info
(
dispex_data_t
*
dispex_info
,
compat_mode_t
compat_mode
)
{
static
const
dispex_hook_t
IEventTarget_hooks
[]
=
{
{
DISPID_IEVENTTARGET_ADDEVENTLISTENER
,
IEventTarget_addEventListener_hook
},
{
DISPID_UNKNOWN
}
};
if
(
compat_mode
>=
COMPAT_MODE_IE9
)
dispex_info_add_interface
(
dispex_info
,
IEventTarget_tid
,
NULL
);
dispex_info_add_interface
(
dispex_info
,
IEventTarget_tid
,
IEventTarget_hooks
);
}
static
int
event_id_cmp
(
const
void
*
key
,
const
struct
wine_rb_entry
*
entry
)
...
...
dlls/mshtml/mshtml_private.h
View file @
d84f6f72
...
...
@@ -283,6 +283,14 @@ typedef struct {
dispex_data_t
*
delayed_init_info
;
}
dispex_static_data_t
;
typedef
HRESULT
(
*
dispex_hook_invoke_t
)(
DispatchEx
*
,
LCID
,
WORD
,
DISPPARAMS
*
,
VARIANT
*
,
EXCEPINFO
*
,
IServiceProvider
*
);
typedef
struct
{
DISPID
dispid
;
dispex_hook_invoke_t
invoke
;
}
dispex_hook_t
;
struct
DispatchEx
{
IDispatchEx
IDispatchEx_iface
;
...
...
@@ -331,7 +339,7 @@ void dispex_unlink(DispatchEx*) DECLSPEC_HIDDEN;
void
release_typelib
(
void
)
DECLSPEC_HIDDEN
;
HRESULT
get_class_typeinfo
(
const
CLSID
*
,
ITypeInfo
**
)
DECLSPEC_HIDDEN
;
const
void
*
dispex_get_vtbl
(
DispatchEx
*
)
DECLSPEC_HIDDEN
;
void
dispex_info_add_interface
(
dispex_data_t
*
,
tid_t
,
const
DISPID
*
)
DECLSPEC_HIDDEN
;
void
dispex_info_add_interface
(
dispex_data_t
*
,
tid_t
,
const
dispex_hook_t
*
)
DECLSPEC_HIDDEN
;
compat_mode_t
dispex_compat_mode
(
DispatchEx
*
)
DECLSPEC_HIDDEN
;
static
inline
void
init_dispex
(
DispatchEx
*
dispex
,
IUnknown
*
outer
,
dispex_static_data_t
*
desc
)
...
...
dlls/mshtml/tests/events.js
View file @
d84f6f72
...
...
@@ -62,6 +62,7 @@ function test_listener_order() {
document
.
body
.
onclick
=
record_call
(
"body.onclick"
);
document
.
body
.
addEventListener
(
"click"
,
record_call
(
"body.click(capture)"
),
true
);
document
.
body
.
addEventListener
(
"click"
,
record_call
(
"body.click(bubble)"
),
false
);
document
.
body
.
addEventListener
(
"click"
,
record_call
(
"body.click(bubble2)"
));
document
.
body
.
attachEvent
(
"onclick"
,
record_call
(
"body.click(attached)"
));
div
.
attachEvent
(
"onclick"
,
record_call
(
"div.click(attached)"
));
...
...
@@ -74,9 +75,9 @@ function test_listener_order() {
div
.
click
();
ok
(
calls
===
"window.click(capture),document.click(capture),body.click(capture),"
+
"div.click(attached),div.click(bubble),div.onclick,div.click(capture1),"
+
"div.click(capture2),body.onclick,body.click(bubble),body.click(
attached
),"
+
"
document.click(attached),document.click(bubble),document.onclick
,"
+
"window.click(bubble),"
,
"calls = "
+
calls
);
+
"div.click(capture2),body.onclick,body.click(bubble),body.click(
bubble2
),"
+
"
body.click(attached),document.click(attached),document.click(bubble)
,"
+
"
document.onclick,
window.click(bubble),"
,
"calls = "
+
calls
);
div
.
onclick
=
record_call
(
"new div.onclick"
);
...
...
@@ -84,9 +85,9 @@ function test_listener_order() {
div
.
click
();
ok
(
calls
===
"window.click(capture),document.click(capture),body.click(capture),"
+
"div.click(attached),div.click(bubble),new div.onclick,div.click(capture1),"
+
"div.click(capture2),body.onclick,body.click(bubble),body.click(
attached
),"
+
"
document.click(attached),document.click(bubble),document.onclick
,"
+
"window.click(bubble),"
,
"calls = "
+
calls
);
+
"div.click(capture2),body.onclick,body.click(bubble),body.click(
bubble2
),"
+
"
body.click(attached),document.click(attached),document.click(bubble)
,"
+
"
document.onclick,
window.click(bubble),"
,
"calls = "
+
calls
);
next_test
();
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment