mshtml: Use generic event dispatcher for DOMContentLoaded.
Use generic event dispatcher instead of nsevent for the DOMContentLoaded event. Also allow processing before dispatching event. Only update dom_content_loaded_event start/end time when the event is trusted.
This commit is contained in:
parent
277acf61d0
commit
54980a7868
4 changed files with 49 additions and 24 deletions
|
@ -6104,6 +6104,38 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI
|
|||
0, flags, dp, res, ei, caller);
|
||||
}
|
||||
|
||||
static HRESULT HTMLDocumentNode_pre_handle_event(DispatchEx* dispex, DOMEvent *event)
|
||||
{
|
||||
HTMLDocumentNode *doc = impl_from_DispatchEx(dispex);
|
||||
switch(event->event_id) {
|
||||
case EVENTID_DOMCONTENTLOADED: {
|
||||
if(event->trusted && doc->window)
|
||||
doc->window->dom_content_loaded_event_start_time = get_time_stamp();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT HTMLDocumentNode_handle_event(DispatchEx* dispex, DOMEvent *event, BOOL *prevent_default)
|
||||
{
|
||||
HTMLDocumentNode *doc = impl_from_DispatchEx(dispex);
|
||||
switch(event->event_id) {
|
||||
case EVENTID_DOMCONTENTLOADED: {
|
||||
if(event->trusted && doc->window)
|
||||
doc->window->dom_content_loaded_event_end_time = get_time_stamp();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
|
||||
{
|
||||
.query_interface = HTMLDocumentNode_query_interface,
|
||||
|
@ -6118,8 +6150,10 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
|
|||
.get_gecko_target = HTMLDocumentNode_get_gecko_target,
|
||||
.bind_event = HTMLDocumentNode_bind_event,
|
||||
.get_parent_event_target = HTMLDocumentNode_get_parent_event_target,
|
||||
.pre_handle_event = HTMLDocumentNode_pre_handle_event,
|
||||
.handle_event = HTMLDocumentNode_handle_event,
|
||||
.get_cp_container = HTMLDocumentNode_get_cp_container,
|
||||
.set_current_event = HTMLDocumentNode_set_current_event
|
||||
.set_current_event = HTMLDocumentNode_set_current_event,
|
||||
};
|
||||
|
||||
static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
|
||||
|
|
|
@ -118,7 +118,7 @@ typedef struct {
|
|||
/* Keep these sorted case sensitively */
|
||||
static const event_info_t event_info[] = {
|
||||
{L"DOMContentLoaded", EVENT_TYPE_EVENT, 0,
|
||||
EVENT_BUBBLES | EVENT_CANCELABLE},
|
||||
EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE },
|
||||
{L"abort", EVENT_TYPE_EVENT, DISPID_EVMETH_ONABORT,
|
||||
EVENT_BIND_TO_TARGET},
|
||||
{L"afterprint", EVENT_TYPE_EVENT, DISPID_EVMETH_ONAFTERPRINT,
|
||||
|
@ -5100,6 +5100,18 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event,
|
|||
IEventTarget_AddRef(&event_target->IEventTarget_iface);
|
||||
|
||||
event->phase = DEP_CAPTURING_PHASE;
|
||||
|
||||
if(event_info[event->event_id].flags & EVENT_HASDEFAULTHANDLERS) {
|
||||
for(i = 0; i < chain_cnt; i++) {
|
||||
vtbl = dispex_get_vtbl(&target_chain[i]->dispex);
|
||||
if(!vtbl->pre_handle_event)
|
||||
continue;
|
||||
hres = vtbl->pre_handle_event(&target_chain[i]->dispex, event);
|
||||
if(FAILED(hres) || event->stop_propagation)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i = chain_cnt-1;
|
||||
while(!event->stop_propagation && i)
|
||||
call_event_handlers(target_chain[i--], event, dispatch_mode);
|
||||
|
|
|
@ -131,6 +131,7 @@ typedef struct {
|
|||
nsISupports *(*get_gecko_target)(DispatchEx*);
|
||||
void (*bind_event)(DispatchEx*,eventid_t);
|
||||
EventTarget *(*get_parent_event_target)(DispatchEx*);
|
||||
HRESULT (*pre_handle_event)(DispatchEx*,DOMEvent*);
|
||||
HRESULT (*handle_event)(DispatchEx*,DOMEvent*,BOOL*);
|
||||
ConnectionPointContainer *(*get_cp_container)(DispatchEx*);
|
||||
IHTMLEventObj *(*set_current_event)(DispatchEx*,IHTMLEventObj*);
|
||||
|
|
|
@ -48,7 +48,6 @@ typedef struct {
|
|||
static nsresult handle_blur(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_focus(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_keypress(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_dom_content_loaded(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_pageshow(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_pagehide(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
static nsresult handle_load(HTMLDocumentNode*,nsIDOMEvent*);
|
||||
|
@ -68,7 +67,6 @@ static const struct {
|
|||
{ EVENTID_BLUR, 0, handle_blur },
|
||||
{ EVENTID_FOCUS, 0, handle_focus },
|
||||
{ EVENTID_KEYPRESS, BUBBLES, handle_keypress },
|
||||
{ EVENTID_DOMCONTENTLOADED, OVERRIDE, handle_dom_content_loaded },
|
||||
{ EVENTID_PAGESHOW, OVERRIDE, handle_pageshow },
|
||||
{ EVENTID_PAGEHIDE, OVERRIDE, handle_pagehide },
|
||||
{ EVENTID_LOAD, OVERRIDE, handle_load },
|
||||
|
@ -234,26 +232,6 @@ static nsresult handle_keypress(HTMLDocumentNode *doc, nsIDOMEvent *event)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult handle_dom_content_loaded(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
|
||||
{
|
||||
DOMEvent *event;
|
||||
HRESULT hres;
|
||||
|
||||
if(doc->window)
|
||||
doc->window->dom_content_loaded_event_start_time = get_time_stamp();
|
||||
|
||||
hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event);
|
||||
if(SUCCEEDED(hres)) {
|
||||
dispatch_event(&doc->node.event_target, event);
|
||||
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||
}
|
||||
|
||||
if(doc->window)
|
||||
doc->window->dom_content_loaded_event_end_time = get_time_stamp();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult handle_pageshow(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
|
||||
{
|
||||
HTMLInnerWindow *window;
|
||||
|
|
Loading…
Add table
Reference in a new issue