Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
d1f1e93c
Commit
d1f1e93c
authored
Oct 25, 2017
by
Jacek Caban
Committed by
Alexandre Julliard
Oct 25, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mshtml: Properly invoke event listeners in IE9+ mode.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b96934bf
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
93 additions
and
7 deletions
+93
-7
htmlevent.c
dlls/mshtml/htmlevent.c
+51
-4
htmlevent.h
dlls/mshtml/htmlevent.h
+2
-1
events.c
dlls/mshtml/tests/events.c
+40
-2
No files found.
dlls/mshtml/htmlevent.c
View file @
d1f1e93c
...
...
@@ -1292,6 +1292,7 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event)
const
eventid_t
eid
=
event
->
event_id
;
const
listener_container_t
*
container
=
get_listener_container
(
event_target
,
eid
,
FALSE
);
const
BOOL
cancelable
=
event_info
[
eid
].
flags
&
EVENT_CANCELABLE
;
const
BOOL
use_quirks
=
use_event_quirks
(
event_target
);
event_listener_t
*
listener
,
listeners_buf
[
8
],
*
listeners
=
listeners_buf
;
unsigned
listeners_cnt
,
listeners_size
;
ConnectionPointContainer
*
cp_container
=
NULL
;
...
...
@@ -1299,9 +1300,10 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event)
VARIANT
v
;
HRESULT
hres
;
if
(
container
&&
!
list_empty
(
&
container
->
listeners
))
{
if
(
use_quirks
&&
container
&&
!
list_empty
(
&
container
->
listeners
)
&&
event
->
phase
!=
DEP_CAPTURING_PHASE
)
{
listener
=
LIST_ENTRY
(
list_tail
(
&
container
->
listeners
),
event_listener_t
,
entry
);
if
(
listener
->
function
&&
listener
->
type
==
LISTENER_TYPE_ONEVENT
)
{
if
(
listener
&&
listener
->
function
&&
listener
->
type
==
LISTENER_TYPE_ONEVENT
)
{
DISPID
named_arg
=
DISPID_THIS
;
VARIANTARG
arg
;
DISPPARAMS
dp
=
{
&
arg
,
&
named_arg
,
1
,
1
};
...
...
@@ -1337,6 +1339,16 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event)
LIST_FOR_EACH_ENTRY
(
listener
,
&
container
->
listeners
,
event_listener_t
,
entry
)
{
if
(
!
listener
->
function
)
continue
;
switch
(
listener
->
type
)
{
case
LISTENER_TYPE_ONEVENT
:
if
(
use_quirks
||
event
->
phase
==
DEP_CAPTURING_PHASE
)
continue
;
break
;
case
LISTENER_TYPE_ATTACHED
:
if
(
event
->
phase
==
DEP_CAPTURING_PHASE
)
continue
;
break
;
}
if
(
listeners_cnt
==
listeners_size
)
{
event_listener_t
*
new_listeners
;
...
...
@@ -1359,7 +1371,37 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event)
}
for
(
listener
=
listeners
;
listener
<
listeners
+
listeners_cnt
;
listener
++
)
{
if
(
listener
->
type
==
LISTENER_TYPE_ATTACHED
)
{
if
(
listener
->
type
!=
LISTENER_TYPE_ATTACHED
)
{
DISPID
named_arg
=
DISPID_THIS
;
VARIANTARG
args
[
2
];
DISPPARAMS
dp
=
{
args
,
&
named_arg
,
2
,
1
};
V_VT
(
args
)
=
VT_DISPATCH
;
V_DISPATCH
(
args
)
=
(
IDispatch
*
)
&
event_target
->
dispex
.
IDispatchEx_iface
;
V_VT
(
args
+
1
)
=
VT_DISPATCH
;
V_DISPATCH
(
args
+
1
)
=
event
->
in_fire_event
?
(
IDispatch
*
)
event
->
event_obj
:
(
IDispatch
*
)
&
event
->
IDOMEvent_iface
;
V_VT
(
&
v
)
=
VT_EMPTY
;
TRACE
(
"%s >>>
\n
"
,
debugstr_w
(
event_info
[
event
->
event_id
].
name
));
hres
=
call_disp_func
(
listener
->
function
,
&
dp
,
&
v
);
if
(
hres
==
S_OK
)
{
TRACE
(
"%s <<< %s
\n
"
,
debugstr_w
(
event_info
[
event
->
event_id
].
name
),
debugstr_variant
(
&
v
));
if
(
cancelable
)
{
if
(
V_VT
(
&
v
)
==
VT_BOOL
)
{
if
(
!
V_BOOL
(
&
v
))
IDOMEvent_preventDefault
(
&
event
->
IDOMEvent_iface
);
}
else
if
(
V_VT
(
&
v
)
!=
VT_EMPTY
)
{
FIXME
(
"unhandled result %s
\n
"
,
debugstr_variant
(
&
v
));
}
}
VariantClear
(
&
v
);
}
else
{
WARN
(
"%s <<< %08x
\n
"
,
debugstr_w
(
event_info
[
event
->
event_id
].
name
),
hres
);
}
}
else
{
VARIANTARG
arg
;
DISPPARAMS
dp
=
{
&
arg
,
NULL
,
1
,
0
};
...
...
@@ -1588,7 +1630,9 @@ HRESULT fire_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_va
if
(
SUCCEEDED
(
hres
))
{
event_obj
->
event
->
event_obj
=
&
event_obj
->
IHTMLEventObj_iface
;
event_obj
->
event
->
in_fire_event
++
;
dispatch_event
(
&
node
->
event_target
,
event_obj
->
event
);
event_obj
->
event
->
in_fire_event
--
;
event_obj
->
event
->
event_obj
=
NULL
;
}
...
...
@@ -1826,7 +1870,10 @@ HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARI
listener
->
type
=
LISTENER_TYPE_ATTACHED
;
IDispatch_AddRef
(
listener
->
function
=
disp
);
list_add_head
(
&
container
->
listeners
,
&
listener
->
entry
);
if
(
use_event_quirks
(
event_target
))
list_add_head
(
&
container
->
listeners
,
&
listener
->
entry
);
else
list_add_tail
(
&
container
->
listeners
,
&
listener
->
entry
);
*
res
=
VARIANT_TRUE
;
return
S_OK
;
...
...
dlls/mshtml/htmlevent.h
View file @
d1f1e93c
...
...
@@ -66,10 +66,11 @@ typedef struct {
EventTarget
*
target
;
BOOL
prevent_default
;
BOOL
stop_propagation
;
USHORT
phase
;
DOM_EVENT_PHASE
phase
;
IHTMLEventObj
*
event_obj
;
BOOL
no_event_obj
;
unsigned
in_fire_event
;
}
DOMEvent
;
void
check_event_attr
(
HTMLDocumentNode
*
,
nsIDOMHTMLElement
*
)
DECLSPEC_HIDDEN
;
...
...
dlls/mshtml/tests/events.c
View file @
d1f1e93c
...
...
@@ -93,6 +93,7 @@ static IHTMLWindow2 *window;
static
IOleDocumentView
*
view
;
static
BOOL
is_ie9plus
;
static
int
document_mode
;
static
unsigned
in_fire_event
;
typedef
struct
{
LONG
x
;
...
...
@@ -358,7 +359,9 @@ static void _elem_fire_event(unsigned line, IUnknown *unk, const char *event, VA
b
=
100
;
str
=
a2bstr
(
event
);
in_fire_event
++
;
hres
=
IHTMLElement3_fireEvent
(
elem3
,
str
,
evobj
,
&
b
);
in_fire_event
--
;
SysFreeString
(
str
);
ok_
(
__FILE__
,
line
)(
hres
==
S_OK
,
"fireEvent failed: %08x
\n
"
,
hres
);
ok_
(
__FILE__
,
line
)(
b
==
VARIANT_TRUE
,
"fireEvent returned %x
\n
"
,
b
);
...
...
@@ -371,20 +374,51 @@ static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD
ok_
(
__FILE__
,
line
)
(
id
==
DISPID_VALUE
,
"id = %d
\n
"
,
id
);
ok_
(
__FILE__
,
line
)
(
wFlags
==
DISPATCH_METHOD
,
"wFlags = %x
\n
"
,
wFlags
);
ok_
(
__FILE__
,
line
)
(
pdp
!=
NULL
,
"pdp == NULL
\n
"
);
todo_wine_if
(
document_mode
>=
9
)
ok_
(
__FILE__
,
line
)
(
pdp
->
cArgs
==
(
document_mode
<
9
?
1
:
2
),
"pdp->cArgs = %d
\n
"
,
pdp
->
cArgs
);
ok_
(
__FILE__
,
line
)
(
pdp
->
cNamedArgs
==
1
,
"pdp->cNamedArgs = %d
\n
"
,
pdp
->
cNamedArgs
);
ok_
(
__FILE__
,
line
)
(
pdp
->
rgdispidNamedArgs
[
0
]
==
DISPID_THIS
,
"pdp->rgdispidNamedArgs[0] = %d
\n
"
,
pdp
->
rgdispidNamedArgs
[
0
]);
ok_
(
__FILE__
,
line
)
(
V_VT
(
pdp
->
rgvarg
)
==
VT_DISPATCH
,
"V_VT(rgvarg) = %d
\n
"
,
V_VT
(
pdp
->
rgvarg
));
if
(
pdp
->
cArgs
>
1
)
ok_
(
__FILE__
,
line
)
(
V_VT
(
pdp
->
rgvarg
+
1
)
==
VT_DISPATCH
,
"V_VT(rgvarg) = %d
\n
"
,
V_VT
(
pdp
->
rgvarg
));
ok_
(
__FILE__
,
line
)
(
V_VT
(
pdp
->
rgvarg
+
1
)
==
VT_DISPATCH
,
"V_VT(rgvarg) = %d
\n
"
,
V_VT
(
pdp
->
rgvarg
+
1
));
ok_
(
__FILE__
,
line
)
(
pvarRes
!=
NULL
,
"pvarRes == NULL
\n
"
);
ok_
(
__FILE__
,
line
)
(
pei
!=
NULL
,
"pei == NULL"
);
ok_
(
__FILE__
,
line
)
(
!
pspCaller
,
"pspCaller != NULL
\n
"
);
if
(
dispiid
)
_test_disp
(
line
,
(
IUnknown
*
)
V_DISPATCH
(
pdp
->
rgvarg
),
dispiid
);
if
(
pdp
->
cArgs
>
1
)
{
IHTMLEventObj
*
window_event
,
*
event_obj
;
IDOMEvent
*
event
;
HRESULT
hres
;
hres
=
IDispatch_QueryInterface
(
V_DISPATCH
(
pdp
->
rgvarg
+
1
),
&
IID_IDOMEvent
,
(
void
**
)
&
event
);
if
(
in_fire_event
)
ok
(
hres
==
E_NOINTERFACE
,
"QI(IID_IDOMEvent) returned %08x
\n
"
,
hres
);
else
ok
(
hres
==
S_OK
,
"Could not get IDOMEvent iface: %08x
\n
"
,
hres
);
hres
=
IDispatch_QueryInterface
(
V_DISPATCH
(
pdp
->
rgvarg
+
1
),
&
IID_IHTMLEventObj
,
(
void
**
)
&
event_obj
);
if
(
in_fire_event
)
ok
(
hres
==
S_OK
,
"Could not get IDOMEventObj iface: %08x
\n
"
,
hres
);
else
ok
(
hres
==
E_NOINTERFACE
,
"QI(IID_IHTMLEventObj) returned %08x
\n
"
,
hres
);
if
(
event
)
IDOMEvent_Release
(
event
);
if
(
event_obj
)
IHTMLEventObj_Release
(
event_obj
);
hres
=
IHTMLWindow2_get_event
(
window
,
&
window_event
);
ok
(
hres
==
S_OK
,
"get_event failed: %08x
\n
"
,
hres
);
if
(
window_event
)
{
todo_wine_if
(
in_fire_event
)
ok
(
!
iface_cmp
((
IUnknown
*
)
V_DISPATCH
(
pdp
->
rgvarg
+
1
),
(
IUnknown
*
)
window_event
),
"window_event != event arg
\n
"
);
IHTMLEventObj_Release
(
window_event
);
}
}
}
#define test_attached_event_args(a,b,c,d,e) _test_attached_event_args(__LINE__,a,b,c,d,e)
...
...
@@ -666,6 +700,7 @@ static void _test_event_srcfilter(unsigned line, IHTMLEventObj *event)
static
void
_test_event_obj
(
unsigned
line
,
const
char
*
type
,
const
xy_test_t
*
xy
)
{
IHTMLEventObj
*
event
=
_get_event_obj
(
line
);
IDOMEvent
*
dom_event
;
VARIANT
v
;
HRESULT
hres
;
...
...
@@ -699,6 +734,9 @@ static void _test_event_obj(unsigned line, const char *type, const xy_test_t *xy
if
(
V_VT
(
&
v
)
==
VT_BOOL
)
ok_
(
__FILE__
,
line
)(
V_BOOL
(
&
v
)
==
VARIANT_TRUE
,
"V_BOOL(returnValue) = %x
\n
"
,
V_BOOL
(
&
v
));
hres
=
IHTMLEventObj_QueryInterface
(
event
,
&
IID_IDOMEvent
,
(
void
**
)
&
dom_event
);
ok
(
hres
==
E_NOINTERFACE
,
"Could not get IDOMEvent iface: %08x
\n
"
,
hres
);
IHTMLEventObj_Release
(
event
);
}
...
...
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