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
57b83052
Commit
57b83052
authored
Oct 19, 2017
by
Jacek Caban
Committed by
Alexandre Julliard
Oct 19, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mshtml: Use event target vtbl to construct target chain in fire_event_obj.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
9e0c990b
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
94 additions
and
84 deletions
+94
-84
htmldoc.c
dlls/mshtml/htmldoc.c
+10
-0
htmlelem.c
dlls/mshtml/htmlelem.c
+23
-1
htmlevent.c
dlls/mshtml/htmlevent.c
+48
-71
htmlevent.h
dlls/mshtml/htmlevent.h
+2
-1
htmlwindow.c
dlls/mshtml/htmlwindow.c
+1
-1
nsembed.c
dlls/mshtml/nsembed.c
+1
-1
nsevents.c
dlls/mshtml/nsevents.c
+5
-5
persist.c
dlls/mshtml/persist.c
+2
-2
script.c
dlls/mshtml/script.c
+2
-2
No files found.
dlls/mshtml/htmldoc.c
View file @
57b83052
...
...
@@ -5030,6 +5030,15 @@ static void HTMLDocumentNode_bind_event(DispatchEx *dispex, eventid_t eid)
ensure_doc_nsevent_handler
(
This
,
eid
);
}
static
EventTarget
*
HTMLDocumentNode_get_parent_event_target
(
DispatchEx
*
dispex
)
{
HTMLDocumentNode
*
This
=
impl_from_DispatchEx
(
dispex
);
if
(
!
This
->
window
)
return
NULL
;
IHTMLWindow2_AddRef
(
&
This
->
window
->
base
.
IHTMLWindow2_iface
);
return
&
This
->
window
->
event_target
;
}
static
ConnectionPointContainer
*
HTMLDocumentNode_get_cp_container
(
DispatchEx
*
dispex
)
{
HTMLDocumentNode
*
This
=
impl_from_DispatchEx
(
dispex
);
...
...
@@ -5048,6 +5057,7 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
NULL
},
HTMLDocumentNode_bind_event
,
HTMLDocumentNode_get_parent_event_target
,
NULL
,
HTMLDocumentNode_get_cp_container
};
...
...
dlls/mshtml/htmlelem.c
View file @
57b83052
...
...
@@ -5191,7 +5191,7 @@ HRESULT HTMLElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *eve
switch
(
code
)
{
case
VK_F1
:
/* DOM_VK_F1 */
TRACE
(
"F1 pressed
\n
"
);
fire_event
(
This
->
node
.
doc
,
EVENTID_HELP
,
TRUE
,
&
This
->
node
,
NULL
);
fire_event
(
This
->
node
.
doc
,
EVENTID_HELP
,
TRUE
,
&
This
->
node
.
event_target
,
NULL
);
*
prevent_default
=
TRUE
;
}
...
...
@@ -5356,6 +5356,27 @@ static HRESULT HTMLElement_handle_event_default(DispatchEx *dispex, eventid_t ei
return
This
->
node
.
vtbl
->
handle_event
(
&
This
->
node
,
eid
,
nsevent
,
prevent_default
);
}
static
EventTarget
*
HTMLElement_get_parent_event_target
(
DispatchEx
*
dispex
)
{
HTMLElement
*
This
=
impl_from_DispatchEx
(
dispex
);
HTMLDOMNode
*
node
;
nsIDOMNode
*
nsnode
;
nsresult
nsres
;
HRESULT
hres
;
nsres
=
nsIDOMNode_GetParentNode
(
This
->
node
.
nsnode
,
&
nsnode
);
assert
(
nsres
==
NS_OK
);
if
(
!
nsnode
)
return
NULL
;
hres
=
get_node
(
This
->
node
.
doc
,
nsnode
,
TRUE
,
&
node
);
nsIDOMNode_Release
(
nsnode
);
if
(
FAILED
(
hres
))
return
NULL
;
return
&
node
->
event_target
;
}
static
ConnectionPointContainer
*
HTMLElement_get_cp_container
(
DispatchEx
*
dispex
)
{
HTMLElement
*
This
=
impl_from_DispatchEx
(
dispex
);
...
...
@@ -5394,6 +5415,7 @@ static event_target_vtbl_t HTMLElement_event_target_vtbl = {
HTMLElement_populate_props
},
HTMLElement_bind_event
,
HTMLElement_get_parent_event_target
,
HTMLElement_handle_event_default
,
HTMLElement_get_cp_container
};
...
...
dlls/mshtml/htmlevent.c
View file @
57b83052
...
...
@@ -1063,16 +1063,15 @@ void call_event_handlers(HTMLEventObj *event_obj, EventTarget *event_target, eve
}
}
static
void
fire_event_obj
(
HTMLDocumentNode
*
doc
,
eventid_t
eid
,
HTMLEventObj
*
event_obj
,
HTMLDOMNode
*
target
)
static
void
fire_event_obj
(
HTMLDocumentNode
*
doc
,
eventid_t
eid
,
HTMLEventObj
*
event_obj
,
EventTarget
*
event_target
)
{
EventTarget
*
target_chain_buf
[
8
],
**
target_chain
=
target_chain_buf
;
unsigned
chain_cnt
,
chain_buf_size
,
i
;
IHTMLEventObj
*
prev_event
;
nsIDOMNode
*
parent
,
*
nsnode
=
NULL
;
const
event_target_vtbl_t
*
vtbl
;
BOOL
prevent_default
=
FALSE
;
HTMLInnerWindow
*
window
;
HTMLDOMNode
*
node
;
UINT16
node_type
=
0
;
nsresult
nsres
;
EventTarget
*
iter
;
HRESULT
hres
;
TRACE
(
"(%p) %s
\n
"
,
doc
,
debugstr_w
(
event_info
[
eid
].
name
));
...
...
@@ -1088,84 +1087,62 @@ static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *e
prev_event
=
window
->
event
;
window
->
event
=
event_obj
?
&
event_obj
->
IHTMLEventObj_iface
:
NULL
;
if
(
target
)
{
nsIDOMNode_GetNodeType
(
target
->
nsnode
,
&
node_type
);
nsnode
=
target
->
nsnode
;
nsIDOMNode_AddRef
(
nsnode
);
}
switch
(
node_type
)
{
case
ELEMENT_NODE
:
do
{
hres
=
get_node
(
doc
,
nsnode
,
FALSE
,
&
node
);
if
(
SUCCEEDED
(
hres
)
&&
node
)
{
call_event_handlers
(
event_obj
,
&
node
->
event_target
,
eid
);
node_release
(
node
);
}
iter
=
event_target
;
IDispatchEx_AddRef
(
&
event_target
->
dispex
.
IDispatchEx_iface
);
if
(
!
(
event_info
[
eid
].
flags
&
EVENT_BUBBLES
)
||
(
event_obj
&&
event_obj
->
cancel_bubble
))
break
;
chain_cnt
=
0
;
chain_buf_size
=
sizeof
(
target_chain_buf
)
/
sizeof
(
*
target_chain_buf
)
;
nsIDOMNode_GetParentNode
(
nsnode
,
&
parent
);
nsIDOMNode_Release
(
nsnode
);
nsnode
=
parent
;
if
(
!
nsnode
)
break
;
do
{
if
(
chain_cnt
==
chain_buf_size
)
{
EventTarget
**
new_chain
;
if
(
target_chain
==
target_chain_buf
)
{
new_chain
=
heap_alloc
(
chain_buf_size
*
2
*
sizeof
(
*
new_chain
));
if
(
!
new_chain
)
break
;
memcpy
(
new_chain
,
target_chain
,
chain_buf_size
*
sizeof
(
*
new_chain
));
}
else
{
new_chain
=
heap_realloc
(
target_chain
,
chain_buf_size
*
2
*
sizeof
(
*
new_chain
));
if
(
!
new_chain
)
break
;
}
chain_buf_size
*=
2
;
target_chain
=
new_chain
;
}
nsIDOMNode_GetNodeType
(
nsnode
,
&
node_type
);
}
while
(
node_type
==
ELEMENT_NODE
);
target_chain
[
chain_cnt
++
]
=
iter
;
if
(
!
(
event_info
[
eid
].
flags
&
EVENT_BUBBLES
)
||
(
event_obj
&&
event_obj
->
cancel_bubble
)
)
if
(
!
(
vtbl
=
dispex_get_vtbl
(
&
iter
->
dispex
))
||
!
vtbl
->
get_parent_event_target
)
break
;
/* fallthrough */
iter
=
vtbl
->
get_parent_event_target
(
&
iter
->
dispex
);
}
while
(
iter
);
case
DOCUMENT_NODE
:
call_event_handlers
(
event_obj
,
&
doc
->
node
.
event_target
,
eid
);
for
(
i
=
0
;
i
<
chain_cnt
;
i
++
)
{
call_event_handlers
(
event_obj
,
target_chain
[
i
]
,
eid
);
if
(
!
(
event_info
[
eid
].
flags
&
EVENT_BUBBLES
)
||
(
event_obj
&&
event_obj
->
cancel_bubble
))
break
;
/* fallthrough */
default:
/* window object */
call_event_handlers
(
event_obj
,
&
doc
->
window
->
event_target
,
eid
);
}
if
(
nsnode
)
nsIDOMNode_Release
(
nsnode
);
if
(
event_obj
&&
event_obj
->
prevent_default
)
prevent_default
=
TRUE
;
window
->
event
=
prev_event
;
if
(
target
&&
!
prevent_default
&&
(
event_info
[
eid
].
flags
&
EVENT_HASDEFAULTHANDLERS
))
{
nsnode
=
target
->
nsnode
;
nsIDOMNode_AddRef
(
nsnode
);
do
{
hres
=
get_node
(
doc
,
nsnode
,
TRUE
,
&
node
);
if
(
FAILED
(
hres
))
break
;
if
(
node
)
{
const
event_target_vtbl_t
*
vtbl
=
dispex_get_vtbl
(
&
node
->
event_target
.
dispex
);
if
(
vtbl
&&
vtbl
->
handle_event_default
)
hres
=
vtbl
->
handle_event_default
(
&
node
->
event_target
.
dispex
,
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
))
if
(
event_info
[
eid
].
flags
&
EVENT_HASDEFAULTHANDLERS
)
{
for
(
i
=
0
;
!
prevent_default
&&
i
<
chain_cnt
;
i
++
)
{
vtbl
=
dispex_get_vtbl
(
&
target_chain
[
i
]
->
dispex
);
if
(
!
vtbl
||
!
vtbl
->
handle_event_default
)
continue
;
hres
=
vtbl
->
handle_event_default
(
&
event_target
->
dispex
,
eid
,
event_obj
?
event_obj
->
nsevent
:
NULL
,
&
prevent_default
);
if
(
FAILED
(
hres
)
||
(
event_obj
&&
event_obj
->
cancel_bubble
))
break
;
nsIDOMNode_Release
(
nsnode
);
nsnode
=
parent
;
}
while
(
nsnode
);
if
(
nsnode
)
nsIDOMNode_Release
(
nsnode
);
}
}
for
(
i
=
0
;
i
<
chain_cnt
;
i
++
)
IDispatchEx_Release
(
&
target_chain
[
i
]
->
dispex
.
IDispatchEx_iface
);
if
(
target_chain
!=
target_chain_buf
)
heap_free
(
target_chain
);
if
(
prevent_default
&&
event_obj
&&
event_obj
->
nsevent
)
{
TRACE
(
"calling PreventDefault
\n
"
);
nsIDOMEvent_PreventDefault
(
event_obj
->
nsevent
);
...
...
@@ -1174,7 +1151,7 @@ static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *e
htmldoc_release
(
&
doc
->
basedoc
);
}
void
fire_event
(
HTMLDocumentNode
*
doc
,
eventid_t
eid
,
BOOL
set_event
,
HTMLDOMNode
*
target
,
nsIDOMEvent
*
nsevent
)
void
fire_event
(
HTMLDocumentNode
*
doc
,
eventid_t
eid
,
BOOL
set_event
,
EventTarget
*
target
,
nsIDOMEvent
*
nsevent
)
{
HTMLEventObj
*
event_obj
=
NULL
;
HRESULT
hres
;
...
...
@@ -1184,7 +1161,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, HTMLDOMNod
if
(
!
event_obj
)
return
;
hres
=
set_event_info
(
event_obj
,
&
target
->
event_
target
,
eid
,
doc
,
nsevent
);
hres
=
set_event_info
(
event_obj
,
target
,
eid
,
doc
,
nsevent
);
if
(
FAILED
(
hres
))
{
IHTMLEventObj_Release
(
&
event_obj
->
IHTMLEventObj_iface
);
return
;
...
...
@@ -1236,13 +1213,13 @@ HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *even
if
(
event_obj
)
{
hres
=
set_event_info
(
event_obj
,
&
node
->
event_target
,
eid
,
node
->
doc
,
NULL
);
if
(
SUCCEEDED
(
hres
))
fire_event_obj
(
node
->
doc
,
eid
,
event_obj
,
node
);
fire_event_obj
(
node
->
doc
,
eid
,
event_obj
,
&
node
->
event_target
);
IHTMLEventObj_Release
(
&
event_obj
->
IHTMLEventObj_iface
);
if
(
FAILED
(
hres
))
return
hres
;
}
else
{
fire_event
(
node
->
doc
,
eid
,
TRUE
,
node
,
NULL
);
fire_event
(
node
->
doc
,
eid
,
TRUE
,
&
node
->
event_target
,
NULL
);
}
*
cancelled
=
VARIANT_TRUE
;
/* FIXME */
...
...
dlls/mshtml/htmlevent.h
View file @
57b83052
...
...
@@ -58,7 +58,7 @@ typedef enum {
eventid_t
str_to_eid
(
LPCWSTR
)
DECLSPEC_HIDDEN
;
void
check_event_attr
(
HTMLDocumentNode
*
,
nsIDOMHTMLElement
*
)
DECLSPEC_HIDDEN
;
void
release_event_target
(
EventTarget
*
)
DECLSPEC_HIDDEN
;
void
fire_event
(
HTMLDocumentNode
*
,
eventid_t
,
BOOL
,
HTMLDOMNode
*
,
nsIDOMEvent
*
)
DECLSPEC_HIDDEN
;
void
fire_event
(
HTMLDocumentNode
*
,
eventid_t
,
BOOL
,
EventTarget
*
,
nsIDOMEvent
*
)
DECLSPEC_HIDDEN
;
HRESULT
set_event_handler
(
EventTarget
*
,
eventid_t
,
VARIANT
*
)
DECLSPEC_HIDDEN
;
HRESULT
get_event_handler
(
EventTarget
*
,
eventid_t
,
VARIANT
*
)
DECLSPEC_HIDDEN
;
HRESULT
attach_event
(
EventTarget
*
,
BSTR
,
IDispatch
*
,
VARIANT_BOOL
*
)
DECLSPEC_HIDDEN
;
...
...
@@ -83,6 +83,7 @@ void detach_nsevent(HTMLDocumentNode*,const WCHAR*) DECLSPEC_HIDDEN;
typedef
struct
{
dispex_static_data_vtbl_t
dispex_vtbl
;
void
(
*
bind_event
)(
DispatchEx
*
,
eventid_t
);
EventTarget
*
(
*
get_parent_event_target
)(
DispatchEx
*
);
HRESULT
(
*
handle_event_default
)(
DispatchEx
*
,
eventid_t
,
nsIDOMEvent
*
,
BOOL
*
);
ConnectionPointContainer
*
(
*
get_cp_container
)(
DispatchEx
*
);
}
event_target_vtbl_t
;
...
...
dlls/mshtml/htmlwindow.c
View file @
57b83052
...
...
@@ -2155,7 +2155,7 @@ static HRESULT WINAPI HTMLWindow6_postMessage(IHTMLWindow6 *iface, BSTR msg, VAR
return
E_FAIL
;
}
fire_event
(
This
->
inner_window
->
doc
,
EVENTID_MESSAGE
,
TRUE
,
NULL
,
NULL
);
fire_event
(
This
->
inner_window
->
doc
,
EVENTID_MESSAGE
,
TRUE
,
&
This
->
inner_window
->
event_target
,
NULL
);
return
S_OK
;
}
...
...
dlls/mshtml/nsembed.c
View file @
57b83052
...
...
@@ -1499,7 +1499,7 @@ static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuList
if
(
FAILED
(
hres
))
return
NS_ERROR_FAILURE
;
fire_event
(
This
->
doc
->
basedoc
.
doc_node
/* FIXME */
,
EVENTID_CONTEXTMENU
,
TRUE
,
node
,
aEvent
);
fire_event
(
This
->
doc
->
basedoc
.
doc_node
/* FIXME */
,
EVENTID_CONTEXTMENU
,
TRUE
,
&
node
->
event_target
,
aEvent
);
nsres
=
nsIDOMEvent_QueryInterface
(
aEvent
,
&
IID_nsIDOMMouseEvent
,
(
void
**
)
&
event
);
assert
(
NS_SUCCEEDED
(
nsres
));
...
...
dlls/mshtml/nsevents.c
View file @
57b83052
...
...
@@ -269,8 +269,8 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
if
(
doc
->
nsdoc
)
{
flush_pending_tasks
(
doc
->
basedoc
.
task_magic
);
fire_event
(
doc
,
EVENTID_LOAD
,
TRUE
,
&
doc
->
node
,
event
);
fire_event
(
doc
,
EVENTID_LOAD
,
TRUE
,
NULL
,
event
);
fire_event
(
doc
,
EVENTID_LOAD
,
TRUE
,
&
doc
->
node
.
event_target
,
event
);
fire_event
(
doc
,
EVENTID_LOAD
,
TRUE
,
&
doc
->
window
->
event_target
,
event
);
}
else
{
ERR
(
"NULL nsdoc
\n
"
);
nsres
=
NS_ERROR_FAILURE
;
...
...
@@ -328,17 +328,17 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *
switch
(
eid
)
{
case
EVENTID_FOCUS
:
if
(
doc
->
event_vector
[
EVENTID_FOCUSIN
])
fire_event
(
doc
,
EVENTID_FOCUSIN
,
TRUE
,
node
,
NULL
);
fire_event
(
doc
,
EVENTID_FOCUSIN
,
TRUE
,
&
node
->
event_target
,
NULL
);
break
;
case
EVENTID_BLUR
:
if
(
doc
->
event_vector
[
EVENTID_FOCUSOUT
])
fire_event
(
doc
,
EVENTID_FOCUSOUT
,
TRUE
,
node
,
NULL
);
fire_event
(
doc
,
EVENTID_FOCUSOUT
,
TRUE
,
&
node
->
event_target
,
NULL
);
break
;
default:
break
;
}
fire_event
(
doc
,
eid
,
TRUE
,
node
,
event
);
fire_event
(
doc
,
eid
,
TRUE
,
&
node
->
event_target
,
event
);
node_release
(
node
);
return
NS_OK
;
...
...
dlls/mshtml/persist.c
View file @
57b83052
...
...
@@ -449,11 +449,11 @@ static void notif_readystate(HTMLOuterWindow *window)
call_property_onchanged
(
&
window
->
doc_obj
->
basedoc
.
cp_container
,
DISPID_READYSTATE
);
fire_event
(
window
->
base
.
inner_window
->
doc
,
EVENTID_READYSTATECHANGE
,
FALSE
,
&
window
->
base
.
inner_window
->
doc
->
node
,
NULL
);
&
window
->
base
.
inner_window
->
doc
->
node
.
event_target
,
NULL
);
if
(
window
->
frame_element
)
fire_event
(
window
->
frame_element
->
element
.
node
.
doc
,
EVENTID_READYSTATECHANGE
,
TRUE
,
&
window
->
frame_element
->
element
.
node
,
NULL
);
TRUE
,
&
window
->
frame_element
->
element
.
node
.
event_target
,
NULL
);
}
typedef
struct
{
...
...
dlls/mshtml/script.c
View file @
57b83052
...
...
@@ -737,7 +737,7 @@ static void fire_readystatechange_proc(task_t *_task)
return
;
task
->
elem
->
pending_readystatechange_event
=
FALSE
;
fire_event
(
task
->
elem
->
element
.
node
.
doc
,
EVENTID_READYSTATECHANGE
,
FALSE
,
&
task
->
elem
->
element
.
node
,
NULL
);
fire_event
(
task
->
elem
->
element
.
node
.
doc
,
EVENTID_READYSTATECHANGE
,
FALSE
,
&
task
->
elem
->
element
.
node
.
event_target
,
NULL
);
}
static
void
fire_readystatechange_task_destr
(
task_t
*
_task
)
...
...
@@ -773,7 +773,7 @@ static void set_script_elem_readystate(HTMLScriptElement *script_elem, READYSTAT
}
else
{
script_elem
->
pending_readystatechange_event
=
FALSE
;
fire_event
(
script_elem
->
element
.
node
.
doc
,
EVENTID_READYSTATECHANGE
,
FALSE
,
&
script_elem
->
element
.
node
,
NULL
);
&
script_elem
->
element
.
node
.
event_target
,
NULL
);
}
}
}
...
...
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