From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 63 ++++++++++++++++++++++++++++--- dlls/mshtml/tests/documentmode.js | 1 + dlls/mshtml/tests/events.c | 13 +++++++ dlls/mshtml/tests/events.js | 2 + 4 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index adf5422c995..9df40510860 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -1876,11 +1876,19 @@ static HRESULT WINAPI HTMLEventObj5_put_origin(IHTMLEventObj5 *iface, BSTR v) static HRESULT WINAPI HTMLEventObj5_get_origin(IHTMLEventObj5 *iface, BSTR *p) { HTMLEventObj *This = impl_from_IHTMLEventObj5(iface); + IDOMMessageEvent *message_event; + HRESULT hres;
- FIXME("(%p)->(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- *p = NULL; - return S_OK; + if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMessageEvent, (void**)&message_event))) { + *p = NULL; + return S_OK; + } + + hres = IDOMMessageEvent_get_origin(message_event, p); + IDOMMessageEvent_Release(message_event); + return hres; }
static HRESULT WINAPI HTMLEventObj5_put_issession(IHTMLEventObj5 *iface, VARIANT_BOOL v) @@ -3669,6 +3677,7 @@ typedef struct { DOMEvent event; IDOMMessageEvent IDOMMessageEvent_iface; IHTMLWindow2 *source; + BSTR origin; VARIANT data; } DOMMessageEvent;
@@ -3756,8 +3765,14 @@ static HRESULT DOMMessageEvent_get_data_hook(DispatchEx *dispex, WORD flags, DIS static HRESULT WINAPI DOMMessageEvent_get_origin(IDOMMessageEvent *iface, BSTR *p) { DOMMessageEvent *This = impl_from_IDOMMessageEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + if(This->origin) + return (*p = SysAllocStringLen(This->origin, SysStringLen(This->origin))) ? S_OK : E_OUTOFMEMORY; + + *p = NULL; + return S_OK; }
static HRESULT WINAPI DOMMessageEvent_get_source(IDOMMessageEvent *iface, IHTMLWindow2 **p) @@ -3829,6 +3844,7 @@ static void DOMMessageEvent_unlink(DispatchEx *dispex) static void DOMMessageEvent_destructor(DispatchEx *dispex) { DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + SysFreeString(message_event->origin); VariantClear(&message_event->data); DOMEvent_destructor(dispex); } @@ -4602,21 +4618,56 @@ HRESULT create_document_event(HTMLDocumentNode *doc, eventid_t event_id, DOMEven HRESULT create_message_event(HTMLDocumentNode *doc, IHTMLWindow2 *source, VARIANT *data, DOMEvent **ret) { DOMMessageEvent *message_event; + BSTR bstr, origin = NULL; + IHTMLLocation *location; DOMEvent *event; HRESULT hres; + UINT len;
- hres = create_document_event(doc, EVENTID_MESSAGE, &event); + hres = IHTMLWindow2_get_location(source, &location); + if(FAILED(hres)) + return hres; + + hres = IHTMLLocation_get_protocol(location, &bstr); + if(FAILED(hres)) { + IHTMLLocation_Release(location); + return hres; + } + len = SysStringLen(bstr); + SysFreeString(bstr); + + hres = IHTMLLocation_get_href(location, &bstr); + IHTMLLocation_Release(location); if(FAILED(hres)) return hres; + if(bstr) { + static const WCHAR delims[] = L"/\"; + + if(bstr[len] == '/' && bstr[len + 1] == '/') + len += 2 + wcscspn(bstr + len + 2, delims); + + origin = SysAllocStringLen(bstr, len); + SysFreeString(bstr); + if(!origin) + return E_OUTOFMEMORY; + } + + hres = create_document_event(doc, EVENTID_MESSAGE, &event); + if(FAILED(hres)) { + SysFreeString(origin); + return hres; + } message_event = DOMMessageEvent_from_DOMEvent(event);
V_VT(&message_event->data) = VT_EMPTY; hres = VariantCopy(&message_event->data, data); if(FAILED(hres)) { IDOMEvent_Release(&event->IDOMEvent_iface); + SysFreeString(origin); return hres; }
+ message_event->origin = origin; message_event->source = source; IHTMLWindow2_AddRef(message_event->source);
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index bec247b42d1..94183ad015e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -2929,6 +2929,7 @@ async_test("postMessage", function() { else { ok(e.data === (v < 10 ? "10" : 10), "e.data = " + e.data); ok(e.source === window, "e.source = " + e.source); + ok(e.origin === "http://winetest.example.org", "e.origin = " + e.origin); next_test(); } } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 8641a2aae7d..0dd622b15c3 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -1542,6 +1542,11 @@ static HRESULT WINAPI onmessage(IDispatchEx *iface, DISPID id, LCID lcid, WORD w ok(!wcscmp(bstr, L"foobar"), "data = %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);
+ hres = IHTMLEventObj5_get_origin(event_obj5, &bstr); + ok(hres == S_OK, "get_origin failed: %08lx\n", hres); + ok(!wcscmp(bstr, L"about:"), "origin = %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + hres = IHTMLEventObj5_get_source(event_obj5, &disp); ok(hres == S_OK, "get_source failed: %08lx\n", hres);
@@ -1558,6 +1563,9 @@ static HRESULT WINAPI onmessage(IDispatchEx *iface, DISPID id, LCID lcid, WORD w bstr = SysAllocString(L"foobar"); hres = IHTMLEventObj5_put_url(event_obj5, bstr); ok(hres == DISP_E_MEMBERNOTFOUND, "put_url returned: %08lx\n", hres); + + hres = IHTMLEventObj5_put_origin(event_obj5, bstr); + ok(hres == DISP_E_MEMBERNOTFOUND, "put_origin returned: %08lx\n", hres); SysFreeString(bstr);
IHTMLEventObj5_Release(event_obj5); @@ -1572,6 +1580,11 @@ static HRESULT WINAPI onmessage(IDispatchEx *iface, DISPID id, LCID lcid, WORD w ok(!wcscmp(bstr, L"foobar"), "data = %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);
+ hres = IDOMMessageEvent_get_origin(msg, &bstr); + ok(hres == S_OK, "get_origin failed: %08lx\n", hres); + ok(!wcscmp(bstr, L"about:"), "origin = %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + hres = IDOMMessageEvent_get_source(msg, &source); ok(hres == S_OK, "get_source failed: %08lx\n", hres); ok(source == onmessage_source, "source != onmessage_source\n"); diff --git a/dlls/mshtml/tests/events.js b/dlls/mshtml/tests/events.js index a5f66a2f031..a130917cfda 100644 --- a/dlls/mshtml/tests/events.js +++ b/dlls/mshtml/tests/events.js @@ -830,6 +830,7 @@ async_test("message event", function() { if(listener_called) { ok(e.data === "echo", "e.data (diff origin) = " + e.data); ok(e.source === iframe.contentWindow, "e.source (diff origin) not iframe.contentWindow"); + ok(e.origin === "http://winetest.different.org:1234", "e.origin (diff origin) = " + e.origin); next_test(); return; } @@ -838,6 +839,7 @@ async_test("message event", function() { ok(e.bubbles === false, "bubbles = " + e.bubbles); ok(e.cancelable === false, "cancelable = " + e.cancelable); ok(e.source === window, "e.source = " + e.source); + ok(e.origin === "http://winetest.example.org", "e.origin = " + e.origin);
iframe.onload = function() { iframe.contentWindow.postMessage("echo", "hTtP://WinEtesT.difFerent.ORG:1234"); } iframe.src = "http://winetest.different.org:1234/xhr_iframe.html";