From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 120 +++++++++++++++++++++++++++ dlls/mshtml/htmlevent.h | 1 + dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/mshtml_private_iface.idl | 14 ++++ dlls/mshtml/nsevents.c | 8 ++ dlls/mshtml/tests/documentmode.js | 17 ++++ 6 files changed, 161 insertions(+)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 3f02f455bbf..c8fca5d4936 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -68,6 +68,7 @@ typedef enum { EVENT_TYPE_MOUSE, EVENT_TYPE_FOCUS, EVENT_TYPE_UIEVENT, + EVENT_TYPE_PAGETRANSITION, EVENT_TYPE_MESSAGE, EVENT_TYPE_PROGRESS, EVENT_TYPE_STORAGE, @@ -82,6 +83,7 @@ static const WCHAR *event_types[] = { L"MouseEvent", L"Event", /* FIXME */ L"UIEvent", + L"Event", /* FIXME */ L"MessageEvent", L"ProgressEvent", L"StorageEvent", @@ -182,6 +184,8 @@ static const event_info_t event_info[] = { EVENT_FIXME}, {L"msthumbnailclick", EVENT_TYPE_MOUSE, DISPID_EVPROP_ONMSTHUMBNAILCLICK, EVENT_FIXME}, + {L"pageshow", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGESHOW, + 0}, {L"paste", EVENT_TYPE_CLIPBOARD, DISPID_EVMETH_ONPASTE, EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE}, {L"progress", EVENT_TYPE_PROGRESS, DISPID_EVPROP_PROGRESS, @@ -2209,6 +2213,98 @@ static void DOMKeyboardEvent_destroy(DOMEvent *event) nsIDOMKeyEvent_Release(This->nsevent); }
+typedef struct { + DOMEvent event; + IWinePageTransitionEvent IWinePageTransitionEvent_iface; +} DOMPageTransitionEvent; + +static inline DOMPageTransitionEvent *impl_from_IWinePageTransitionEvent(IWinePageTransitionEvent *iface) +{ + return CONTAINING_RECORD(iface, DOMPageTransitionEvent, IWinePageTransitionEvent_iface); +} + +static HRESULT WINAPI DOMPageTransitionEvent_QueryInterface(IWinePageTransitionEvent *iface, REFIID riid, void **ppv) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDOMEvent_QueryInterface(&This->event.IDOMEvent_iface, riid, ppv); +} + +static ULONG WINAPI DOMPageTransitionEvent_AddRef(IWinePageTransitionEvent *iface) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDOMEvent_AddRef(&This->event.IDOMEvent_iface); +} + +static ULONG WINAPI DOMPageTransitionEvent_Release(IWinePageTransitionEvent *iface) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDOMEvent_Release(&This->event.IDOMEvent_iface); +} + +static HRESULT WINAPI DOMPageTransitionEvent_GetTypeInfoCount(IWinePageTransitionEvent *iface, UINT *pctinfo) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->event.dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI DOMPageTransitionEvent_GetTypeInfo(IWinePageTransitionEvent *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDispatchEx_GetTypeInfo(&This->event.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI DOMPageTransitionEvent_GetIDsOfNames(IWinePageTransitionEvent *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->event.dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI DOMPageTransitionEvent_Invoke(IWinePageTransitionEvent *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + return IDispatchEx_Invoke(&This->event.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI DOMPageTransitionEvent_get_persisted(IWinePageTransitionEvent *iface, VARIANT_BOOL *p) +{ + DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface); + + FIXME("(%p)->(%p): always returning FALSE\n", This, p); + + *p = VARIANT_FALSE; + return S_OK; +} + +static const IWinePageTransitionEventVtbl DOMPageTransitionEventVtbl = { + DOMPageTransitionEvent_QueryInterface, + DOMPageTransitionEvent_AddRef, + DOMPageTransitionEvent_Release, + DOMPageTransitionEvent_GetTypeInfoCount, + DOMPageTransitionEvent_GetTypeInfo, + DOMPageTransitionEvent_GetIDsOfNames, + DOMPageTransitionEvent_Invoke, + DOMPageTransitionEvent_get_persisted +}; + +static DOMPageTransitionEvent *DOMPageTransitionEvent_from_DOMEvent(DOMEvent *event) +{ + return CONTAINING_RECORD(event, DOMPageTransitionEvent, event); +} + +static void *DOMPageTransitionEvent_query_interface(DOMEvent *event, REFIID riid) +{ + DOMPageTransitionEvent *page_transition_event = DOMPageTransitionEvent_from_DOMEvent(event); + if(IsEqualGUID(&IID_IWinePageTransitionEvent, riid)) + return &page_transition_event->IWinePageTransitionEvent_iface; + return NULL; +} + typedef struct { DOMEvent event; IDOMCustomEvent IDOMCustomEvent_iface; @@ -2837,6 +2933,20 @@ static dispex_static_data_t DOMKeyboardEvent_dispex = { DOMKeyboardEvent_iface_tids };
+static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + if(mode >= COMPAT_MODE_IE11) + dispex_info_add_interface(info, IWinePageTransitionEvent_tid, NULL); +} + +dispex_static_data_t DOMPageTransitionEvent_dispex = { + L"PageTransitionEvent", + NULL, + DispDOMEvent_tid, + DOMEvent_iface_tids, + DOMPageTransitionEvent_init_dispex_info +}; + static const tid_t DOMCustomEvent_iface_tids[] = { IDOMEvent_tid, IDOMCustomEvent_tid, @@ -2961,6 +3071,15 @@ static DOMEvent *keyboard_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_ return &keyboard_event->ui_event.event; }
+static DOMEvent *page_transition_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) +{ + DOMPageTransitionEvent *page_transition_event = event_ctor(sizeof(DOMCustomEvent), &DOMPageTransitionEvent_dispex, + DOMPageTransitionEvent_query_interface, NULL, nsevent, event_id, compat_mode); + if(!page_transition_event) return NULL; + page_transition_event->IWinePageTransitionEvent_iface.lpVtbl = &DOMPageTransitionEventVtbl; + return &page_transition_event->event; +} + static DOMEvent *custom_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), &DOMCustomEvent_dispex, @@ -3015,6 +3134,7 @@ static const struct { [EVENT_TYPE_CLIPBOARD] = { NULL, generic_event_ctor }, [EVENT_TYPE_FOCUS] = { NULL, generic_event_ctor }, [EVENT_TYPE_DRAG] = { NULL, generic_event_ctor }, + [EVENT_TYPE_PAGETRANSITION] = { NULL, page_transition_event_ctor }, [EVENT_TYPE_CUSTOM] = { &IID_nsIDOMCustomEvent, custom_event_ctor }, [EVENT_TYPE_PROGRESS] = { &IID_nsIDOMProgressEvent, progress_event_ctor }, [EVENT_TYPE_MESSAGE] = { NULL, message_event_ctor }, diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 97baf9eed7b..e49c47d6988 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -51,6 +51,7 @@ typedef enum { EVENTID_MOUSEUP, EVENTID_MOUSEWHEEL, EVENTID_MSTHUMBNAILCLICK, + EVENTID_PAGESHOW, EVENTID_PASTE, EVENTID_PROGRESS, EVENTID_READYSTATECHANGE, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index e3971258b13..7e7dd358c8d 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -288,6 +288,7 @@ typedef struct EventTarget EventTarget; XIID(IWineHTMLElementPrivate) \ XIID(IWineHTMLWindowPrivate) \ XIID(IWineHTMLWindowCompatPrivate) \ + XIID(IWinePageTransitionEvent) \ XIID(IWineXMLHttpRequestPrivate) \ XIID(IWineMSHTMLConsole) \ XIID(IWineMSHTMLMediaQueryList) diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index fc023473cc9..8e4a64bda39 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -162,6 +162,20 @@ interface IWineDOMTokenList : IDispatch HRESULT toString([retval, out] BSTR *String); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(25508c5d-6a54-6888-8f41-75ff3ae8706b) +] +interface IWinePageTransitionEvent : IDispatch +{ + [propget, id(1)] + HRESULT persisted([retval, out] VARIANT_BOOL *ret); +} + + const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE = 1; const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE = 2; const long DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD = 3; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 17904963188..fea86480be0 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -274,6 +274,14 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event dispatch_event(&doc->window->event_target, load_event); IDOMEvent_Release(&load_event->IDOMEvent_iface); } + + if(doc->dom_document && doc->document_mode >= COMPAT_MODE_IE11) { + hres = create_document_event(doc, EVENTID_PAGESHOW, &load_event); + if(SUCCEEDED(hres)) { + dispatch_event(&doc->window->event_target, load_event); + IDOMEvent_Release(&load_event->IDOMEvent_iface); + } + } }else { WARN("no window\n"); } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 7d26add1cfc..0ae5df94b3a 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -19,10 +19,27 @@ var compat_version; var tests = [];
+var pageshow_fired = false; if(window.addEventListener) { + window.addEventListener("pageshow", function(e) { + pageshow_fired = true; + + var r = Object.prototype.toString.call(e); + todo_wine. + ok(r === "[object PageTransitionEvent]", "pageshow toString = " + r); + ok("persisted" in e, "'persisted' not in pageshow event"); + ok(document.readyState === "complete", "pageshow readyState = " + document.readyState); + }, true); + document.addEventListener("visibilitychange", function() { ok(false, "visibilitychange fired"); }); }
+sync_test("page transition events", function() { + if(document.documentMode < 11) + ok(pageshow_fired === false, "pageshow fired"); + else + ok(pageshow_fired === true, "pageshow not fired"); +});
sync_test("builtin_toString", function() { var tags = [