Bunch of misc fixes and preparations for further improvements. The location changes are especially important later when we'll use outer windows everywhere we pass them to external callers (such as script engines, since inner windows are an implementation detail and all operations otherwise should go through the outer window "proxy").
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- include/mshtmdid.h | 11 ++ include/mshtml.idl | 357 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 368 insertions(+)
diff --git a/include/mshtmdid.h b/include/mshtmdid.h index 1673dd3cea0..a28d706903f 100644 --- a/include/mshtmdid.h +++ b/include/mshtmdid.h @@ -3487,6 +3487,17 @@ /* IHTMLEventObj4 */ #define DISPID_IHTMLEVENTOBJ4_WHEELDELTA DISPID_EVENTOBJ+51
+/* IHTMLEventObj5 */ +#define DISPID_IHTMLEVENTOBJ5_URL DISPID_EVENTOBJ+52 +#define DISPID_IHTMLEVENTOBJ5_DATA DISPID_EVENTOBJ+54 +#define DISPID_IHTMLEVENTOBJ5_SOURCE DISPID_EVENTOBJ+55 +#define DISPID_IHTMLEVENTOBJ5_ORIGIN DISPID_EVENTOBJ+53 +#define DISPID_IHTMLEVENTOBJ5_ISSESSION DISPID_EVENTOBJ+56 + +/* IHTMLEventObj6 */ +#define DISPID_IHTMLEVENTOBJ6_ACTIONURL DISPID_EVENTOBJ+58 +#define DISPID_IHTMLEVENTOBJ6_BUTTONID DISPID_EVENTOBJ+57 + /* IHTMLStyleMedia */ #define DISPID_IHTMLSTYLEMEDIA_TYPE DISPID_STYLEMEDIA+1 #define DISPID_IHTMLSTYLEMEDIA_MATCHMEDIUM DISPID_STYLEMEDIA+2 diff --git a/include/mshtml.idl b/include/mshtml.idl index 1a5c9bbaf28..2a1fccba6be 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -19400,6 +19400,327 @@ interface IHTMLEventObj : IDispatch HRESULT srcFilter([retval, out] IDispatch **p); }
+/***************************************************************************** + * IHTMLEventObj2 interface + */ +[ + odl, + oleautomation, + dual, + uuid(3050f48B-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLEventObj2 : IDispatch +{ + [id(DISPID_IHTMLEVENTOBJ2_SETATTRIBUTE)] + HRESULT setAttribute( + [in] BSTR strAttributeName, + [in] VARIANT AttributeValue, + [in, defaultvalue(1)] LONG lFlags); + + [id(DISPID_IHTMLEVENTOBJ2_GETATTRIBUTE)] + HRESULT getAttribute( + [in] BSTR strAttributeName, + [in, defaultvalue(0)] LONG lFlags, + [out, retval] VARIANT *AttributeValue); + + [id(DISPID_IHTMLEVENTOBJ2_REMOVEATTRIBUTE)] + HRESULT removeAttribute( + [in] BSTR strAttributeName, + [in, defaultvalue(1)] LONG lFlags, + [out, retval] VARIANT_BOOL *pfSuccess); + + [propput, id(DISPID_IHTMLEVENTOBJ2_PROPERTYNAME)] + HRESULT propertyName([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_PROPERTYNAME)] + HRESULT propertyName([out, retval] BSTR *p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_BOOKMARKS)] + HRESULT bookmarks([in] IHTMLBookmarkCollection *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_BOOKMARKS)] + HRESULT bookmarks([out, retval] IHTMLBookmarkCollection **p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_RECORDSET)] + HRESULT recordset([in] IDispatch *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_RECORDSET)] + HRESULT recordset([out, retval] IDispatch **p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_DATAFLD)] + HRESULT dataFld([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_DATAFLD)] + HRESULT dataFld([out, retval] BSTR *p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_BOUNDELEMENTS)] + HRESULT boundElements([in] IHTMLElementCollection *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_BOUNDELEMENTS)] + HRESULT boundElements([out, retval] IHTMLElementCollection **p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_REPEAT)] + HRESULT repeat([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_REPEAT)] + HRESULT repeat([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_SRCURN)] + HRESULT srcUrn([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SRCURN)] + HRESULT srcUrn([out, retval] BSTR *p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_SRCELEMENT)] + HRESULT srcElement([in] IHTMLElement *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SRCELEMENT)] + HRESULT srcElement([out, retval] IHTMLElement **p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_ALTKEY)] + HRESULT altKey([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_ALTKEY)] + HRESULT altKey([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_CTRLKEY)] + HRESULT ctrlKey([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_CTRLKEY)] + HRESULT ctrlKey([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_SHIFTKEY)] + HRESULT shiftKey([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SHIFTKEY)] + HRESULT shiftKey([out, retval] VARIANT_BOOL *p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_FROMELEMENT)] + HRESULT fromElement([in] IHTMLElement *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_FROMELEMENT)] + HRESULT fromElement([out, retval] IHTMLElement **p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_TOELEMENT)] + HRESULT toElement([in] IHTMLElement *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_TOELEMENT)] + HRESULT toElement([out, retval] IHTMLElement **p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_BUTTON)] + HRESULT button([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_BUTTON)] + HRESULT button([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_TYPE)] + HRESULT type([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_TYPE)] + HRESULT type([out, retval] BSTR *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_QUALIFIER)] + HRESULT qualifier([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_QUALIFIER)] + HRESULT qualifier([out, retval] BSTR *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_REASON)] + HRESULT reason([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_REASON)] + HRESULT reason([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_X)] + HRESULT x([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_X)] + HRESULT x([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_Y)] + HRESULT y([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_Y)] + HRESULT y([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_CLIENTX)] + HRESULT clientX([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_CLIENTX)] + HRESULT clientX([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_CLIENTY)] + HRESULT clientY([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_CLIENTY)] + HRESULT clientY([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_OFFSETX)] + HRESULT offsetX([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_OFFSETX)] + HRESULT offsetX([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_OFFSETY)] + HRESULT offsetY([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_OFFSETY)] + HRESULT offsetY([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_SCREENX)] + HRESULT screenX([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SCREENX)] + HRESULT screenX([out, retval] long *p); + + [propput, id(DISPID_IHTMLEVENTOBJ2_SCREENY)] + HRESULT screenY([in] long v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SCREENY)] + HRESULT screenY([out, retval] long *p); + + [propputref, id(DISPID_IHTMLEVENTOBJ2_SRCFILTER)] + HRESULT srcFilter([in] IDispatch *v); + + [propget, id(DISPID_IHTMLEVENTOBJ2_SRCFILTER)] + HRESULT srcFilter([out, retval] IDispatch **p); + + [propget, id(DISPID_IHTMLEVENTOBJ2_DATATRANSFER)] + HRESULT dataTransfer([out, retval] IHTMLDataTransfer **p); +} + +/***************************************************************************** + * IHTMLEventObj3 interface + */ +[ + odl, + oleautomation, + dual, + uuid(3050f680-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLEventObj3 : IDispatch +{ + [propget, id(DISPID_IHTMLEVENTOBJ3_CONTENTOVERFLOW)] + HRESULT contentOverflow([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ3_SHIFTLEFT)] + HRESULT shiftLeft([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ3_SHIFTLEFT)] + HRESULT shiftLeft([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ3_ALTLEFT)] + HRESULT altLeft([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ3_ALTLEFT)] + HRESULT altLeft([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLEVENTOBJ3_CTRLLEFT)] + HRESULT ctrlLeft([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ3_CTRLLEFT)] + HRESULT ctrlLeft([out, retval] VARIANT_BOOL *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_IMECOMPOSITIONCHANGE), hidden, restricted, nonbrowsable] + HRESULT imeCompositionChange([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_IMENOTIFYCOMMAND), hidden, restricted, nonbrowsable] + HRESULT imeNotifyCommand([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_IMENOTIFYDATA), hidden, restricted, nonbrowsable] + HRESULT imeNotifyData([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_IMEREQUEST), hidden, restricted, nonbrowsable] + HRESULT imeRequest([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_IMEREQUESTDATA), hidden, restricted, nonbrowsable] + HRESULT imeRequestData([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_KEYBOARDLAYOUT), hidden, restricted, nonbrowsable] + HRESULT keyboardLayout([out, retval] LONG_PTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_BEHAVIORCOOKIE)] + HRESULT behaviorCookie([out, retval] long *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_BEHAVIORPART)] + HRESULT behaviorPart([out, retval] long *p); + + [propget, id(DISPID_IHTMLEVENTOBJ3_NEXTPAGE)] + HRESULT nextPage([out, retval] BSTR *p); +} + +/***************************************************************************** + * IHTMLEventObj4 interface + */ +[ + odl, + oleautomation, + dual, + uuid(3050f814-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLEventObj4 : IDispatch +{ + [propget, id(DISPID_IHTMLEVENTOBJ4_WHEELDELTA)] + HRESULT wheelDelta([out, retval] long *p); +} + +/***************************************************************************** + * IHTMLEventObj5 interface + */ +[ + odl, + oleautomation, + dual, + uuid(30510478-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLEventObj5 : IDispatch +{ + [propput, id(DISPID_IHTMLEVENTOBJ5_URL)] + HRESULT url([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_URL)] + HRESULT url([out, retval] BSTR *p); + + [propput, id(DISPID_IHTMLEVENTOBJ5_DATA)] + HRESULT data([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_DATA)] + HRESULT data([out, retval] BSTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ5_SOURCE)] + HRESULT source([out, retval] IDispatch **p); + + [propput, id(DISPID_IHTMLEVENTOBJ5_ORIGIN)] + HRESULT origin([in] BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_ORIGIN)] + HRESULT origin([out, retval] BSTR *p); + + [propput, id(DISPID_IHTMLEVENTOBJ5_ISSESSION), hidden, restricted, nonbrowsable] + HRESULT issession([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_ISSESSION), hidden, restricted, nonbrowsable] + HRESULT issession([out, retval] VARIANT_BOOL *p); +} + +/***************************************************************************** + * IHTMLEventObj6 interface + */ +[ + odl, + oleautomation, + dual, + uuid(30510734-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLEventObj6 : IDispatch +{ + [propget, id(DISPID_IHTMLEVENTOBJ6_ACTIONURL)] + HRESULT actionURL([out, retval] BSTR *p); + + [propget, id(DISPID_IHTMLEVENTOBJ6_BUTTONID)] + HRESULT buttonID([out, retval] long *p); +} + /***************************************************************************** * DispCEventObj dispinterface */ @@ -19653,6 +19974,42 @@ methods:
[propget, id(DISPID_IHTMLEVENTOBJ4_WHEELDELTA)] LONG wheelDelta(); + + [propput, id(DISPID_IHTMLEVENTOBJ5_URL)] + void url(BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_URL)] + BSTR url(); + + [propput, id(DISPID_IHTMLEVENTOBJ5_DATA)] + void data(BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_DATA)] + BSTR data(); + + [propget, id(DISPID_IHTMLEVENTOBJ5_SOURCE)] + IDispatch *source(); + + [propput, id(DISPID_IHTMLEVENTOBJ5_ORIGIN)] + void origin(BSTR v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_ORIGIN)] + BSTR origin(); + + [propput, id(DISPID_IHTMLEVENTOBJ5_ISSESSION), hidden, restricted, nonbrowsable] + void issession(VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLEVENTOBJ5_ISSESSION), hidden, restricted, nonbrowsable] + VARIANT_BOOL issession(); + + [propget, id(DISPID_IHTMLEVENTOBJ6_ACTIONURL)] + BSTR actionURL(); + + [propget, id(DISPID_IHTMLEVENTOBJ6_BUTTONID)] + long buttonID(); + + [propget, id(DISPID_IHTMLDOMCONSTRUCTOR_CONSTRUCTOR), hidden] + IDispatch *constructor(); }
/*****************************************************************************
From: Gabriel Ivăncescu gabrielopcode@gmail.com
While Internet Explorer 6 used to default to "always", this hasn't been the case for a long while now.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/nsembed.c | 2 +- dlls/mshtml/oleobj.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index b7518f55ef9..b6d7b53f815 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -2268,7 +2268,7 @@ static HRESULT init_browser(GeckoBrowser *browser) nsres = nsIWebBrowser_QueryInterface(browser->webbrowser, &IID_nsIScrollable, (void**)&scrollable); if(NS_SUCCEEDED(nsres)) { nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, - ScrollOrientation_Y, Scrollbar_Always); + ScrollOrientation_Y, Scrollbar_Auto); if(NS_FAILED(nsres)) ERR("Could not set default Y scrollbar prefs: %08lx\n", nsres);
diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index d1853435606..c01c18b5fa8 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -363,7 +363,7 @@ static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo) nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable); if(NS_SUCCEEDED(nsres)) { nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_Y, - (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Always); + (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Auto); if(NS_FAILED(nsres)) ERR("Could not set default Y scrollbar prefs: %08lx\n", nsres);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/array.c | 18 +++-- dlls/jscript/dispex.c | 23 ++++--- dlls/jscript/engine.c | 10 +-- dlls/jscript/function.c | 2 +- dlls/jscript/jscript.h | 2 +- dlls/jscript/json.c | 4 +- dlls/jscript/set.c | 3 +- dlls/jscript/tests/run.c | 143 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 178 insertions(+), 27 deletions(-)
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index 341505a335c..198fc3c16c1 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -1061,7 +1061,8 @@ static HRESULT Array_every(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigne args[0] = value; args[1] = jsval_number(i); args[2] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res, + &ctx->jscaller->IServiceProvider_iface); jsval_release(value); if(FAILED(hres)) goto done; @@ -1128,7 +1129,8 @@ static HRESULT Array_filter(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsign args[0] = value; args[1] = jsval_number(i); args[2] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res, + &ctx->jscaller->IServiceProvider_iface); if(SUCCEEDED(hres)) { hres = to_boolean(res, &boolval); jsval_release(res); @@ -1190,7 +1192,8 @@ static HRESULT Array_forEach(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsig args[0] = value; args[1] = jsval_number(i); args[2] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res, + &ctx->jscaller->IServiceProvider_iface); jsval_release(value); if(FAILED(hres)) goto done; @@ -1365,7 +1368,8 @@ static HRESULT Array_map(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned
callback_args[1] = jsval_number(k); callback_args[2] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, 3, callback_args, &mapped_value); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, 3, callback_args, &mapped_value, + &ctx->jscaller->IServiceProvider_iface); jsval_release(callback_args[0]); if(FAILED(hres)) break; @@ -1432,7 +1436,8 @@ static HRESULT Array_reduce(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsign callback_args[0] = acc; callback_args[2] = jsval_number(k); callback_args[3] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, jsval_undefined(), DISPATCH_METHOD, ARRAY_SIZE(callback_args), callback_args, &new_acc); + hres = disp_call_value(ctx, callback, jsval_undefined(), DISPATCH_METHOD, ARRAY_SIZE(callback_args), + callback_args, &new_acc, &ctx->jscaller->IServiceProvider_iface); jsval_release(callback_args[1]); if(FAILED(hres)) break; @@ -1493,7 +1498,8 @@ static HRESULT Array_some(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned args[0] = value; args[1] = jsval_number(i); args[2] = jsval_obj(jsthis); - hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res, + &ctx->jscaller->IServiceProvider_iface); jsval_release(value); if(FAILED(hres)) goto done; diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 4b56ec9fc70..73a4a5bbecd 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -574,7 +574,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
return disp_call_value(This->ctx, get_object(prop->u.val), jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface), - flags, argc, argv, r); + flags, argc, argv, r, caller); } case PROP_ACCESSOR: case PROP_IDX: { @@ -587,7 +587,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t if(is_object_instance(val)) { hres = disp_call_value(This->ctx, get_object(val), jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface), - flags, argc, argv, r); + flags, argc, argv, r, caller); }else { FIXME("invoke %s\n", debugstr_jsval(val)); hres = E_NOTIMPL; @@ -2364,7 +2364,7 @@ HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_ if(!prop) return DISP_E_MEMBERNOTFOUND;
- return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL); + return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface); }
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) @@ -2379,10 +2379,11 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned if(!prop || prop->type == PROP_DELETED) return JS_E_INVALID_PROPERTY;
- return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL); + return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface); }
-static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *params, VARIANT *r) +static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *params, VARIANT *r, + IServiceProvider *caller) { IDispatchEx *dispex; EXCEPINFO ei; @@ -2391,7 +2392,7 @@ static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD f memset(&ei, 0, sizeof(ei)); hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); if(SUCCEEDED(hres)) { - hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, params, r, &ei, &ctx->jscaller->IServiceProvider_iface); + hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, params, r, &ei, caller); IDispatchEx_Release(dispex); }else { UINT err = 0; @@ -2489,7 +2490,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns }
V_VT(&retv) = VT_EMPTY; - hres = disp_invoke(ctx, disp, id, flags, &dp, ret ? &retv : NULL); + hres = disp_invoke(ctx, disp, id, flags, &dp, ret ? &retv : NULL, &ctx->jscaller->IServiceProvider_iface);
for(i=0; i<argc; i++) VariantClear(dp.rgvarg+argc-i-1); @@ -2530,7 +2531,7 @@ HRESULT disp_call_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, WO }
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, - jsval_t *r) + jsval_t *r, IServiceProvider *caller) { VARIANT buf[6], retv, *args = buf; IDispatch *jsthis; @@ -2586,7 +2587,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD
if(SUCCEEDED(hres)) { V_VT(&retv) = VT_EMPTY; - hres = disp_invoke(ctx, disp, DISPID_VALUE, flags, &dp, r ? &retv : NULL); + hres = disp_invoke(ctx, disp, DISPID_VALUE, flags, &dp, r ? &retv : NULL, caller); }
for(i = 0; i < argc; i++) @@ -2665,7 +2666,7 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val) if(V_VT(&var) == VT_DISPATCH) flags |= DISPATCH_PROPERTYPUTREF;
- hres = disp_invoke(ctx, disp, id, flags, &dp, NULL); + hres = disp_invoke(ctx, disp, id, flags, &dp, NULL, &ctx->jscaller->IServiceProvider_iface); VariantClear(&var); }
@@ -2773,7 +2774,7 @@ HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val jsdisp_release(jsdisp);
V_VT(&var) = VT_EMPTY; - hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var); + hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var, &ctx->jscaller->IServiceProvider_iface); if(SUCCEEDED(hres)) { hres = variant_to_jsval(ctx, &var, val); VariantClear(&var); diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index b0557065e69..459d1e833df 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -327,7 +327,7 @@ static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsig return E_FAIL; }
- return disp_call_value(ctx, get_object(v), jsval_undefined(), flags, argc, argv, r); + return disp_call_value(ctx, get_object(v), jsval_undefined(), flags, argc, argv, r, &ctx->jscaller->IServiceProvider_iface); } case EXPRVAL_IDREF: /* ECMA-262 3rd Edition 11.2.3.7 / ECMA-262 5.1 Edition 11.2.3.6 * @@ -340,7 +340,7 @@ static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsig FIXME("invoke %s\n", debugstr_jsval(v)); hres = E_FAIL; }else { - hres = disp_call_value(ctx, get_object(v), jsval_undefined(), flags, argc, argv, r); + hres = disp_call_value(ctx, get_object(v), jsval_undefined(), flags, argc, argv, r, &ctx->jscaller->IServiceProvider_iface); } jsval_release(v); return hres; @@ -351,7 +351,7 @@ static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsig
hres = to_object(ctx, ref->u.val, &obj); if(SUCCEEDED(hres)) { - hres = disp_call_value(ctx, obj, jsval_undefined(), flags, argc, argv, r); + hres = disp_call_value(ctx, obj, jsval_undefined(), flags, argc, argv, r, &ctx->jscaller->IServiceProvider_iface); IDispatch_Release(obj); } return hres; @@ -1421,7 +1421,7 @@ static HRESULT interp_new(script_ctx_t *ctx)
clear_acc(ctx); return disp_call_value(ctx, get_object(constr), jsval_undefined(), DISPATCH_CONSTRUCT | DISPATCH_JSCRIPT_CALLEREXECSSOURCE, - argc, stack_args(ctx, argc), &ctx->acc); + argc, stack_args(ctx, argc), &ctx->acc, &ctx->jscaller->IServiceProvider_iface); }
/* ECMA-262 3rd Edition 11.2.3 */ @@ -1439,7 +1439,7 @@ static HRESULT interp_call(script_ctx_t *ctx)
clear_acc(ctx); return disp_call_value(ctx, get_object(obj), jsval_undefined(), DISPATCH_METHOD | DISPATCH_JSCRIPT_CALLEREXECSSOURCE, - argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL); + argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL, &ctx->jscaller->IServiceProvider_iface); }
/* ECMA-262 3rd Edition 11.2.3 */ diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 5f210a04050..c3b22eb843c 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -411,7 +411,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsi hres = function->vtbl->call(ctx, function, this_val, flags, cnt, args, r); }else { jsval_t res; - hres = disp_call_value(ctx, get_object(vthis), this_val, DISPATCH_METHOD, cnt, args, &res); + hres = disp_call_value(ctx, get_object(vthis), this_val, DISPATCH_METHOD, cnt, args, &res, &ctx->jscaller->IServiceProvider_iface); if(SUCCEEDED(hres)) { if(r) *r = res; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 36a6d23c917..04b3a6cc8c9 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -240,7 +240,7 @@ HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,js
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; HRESULT disp_call_name(script_ctx_t*,IDispatch*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; -HRESULT disp_call_value(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; +HRESULT disp_call_value(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*,IServiceProvider*) DECLSPEC_HIDDEN; HRESULT jsdisp_call_value(jsdisp_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/json.c b/dlls/jscript/json.c index e36c4973ef2..d2be768ffea 100644 --- a/dlls/jscript/json.c +++ b/dlls/jscript/json.c @@ -350,8 +350,8 @@ static jsval_t transform_json_object(struct transform_json_object_ctx *proc_ctx, }
args[0] = jsval_string(name); - proc_ctx->hres = disp_call_value(proc_ctx->ctx, proc_ctx->reviver, jsval_obj(holder), - DISPATCH_METHOD, ARRAY_SIZE(args), args, &res); + proc_ctx->hres = disp_call_value(proc_ctx->ctx, proc_ctx->reviver, jsval_obj(holder), DISPATCH_METHOD, + ARRAY_SIZE(args), args, &res, &proc_ctx->ctx->jscaller->IServiceProvider_iface); return FAILED(proc_ctx->hres) ? jsval_undefined() : res; }
diff --git a/dlls/jscript/set.c b/dlls/jscript/set.c index eca26a890f7..cd2ef4bd269 100644 --- a/dlls/jscript/set.c +++ b/dlls/jscript/set.c @@ -208,7 +208,8 @@ static HRESULT iterate_map(MapInstance *map, script_ctx_t *ctx, unsigned argc, j args[1] = entry->key; args[2] = jsval_obj(&map->dispex); grab_map_entry(entry); - hres = disp_call_value(ctx, get_object(argv[0]), context_this, DISPATCH_METHOD, ARRAY_SIZE(args), args, &v); + hres = disp_call_value(ctx, get_object(argv[0]), context_this, DISPATCH_METHOD, ARRAY_SIZE(args), + args, &v, &ctx->jscaller->IServiceProvider_iface); iter = list_next(&map->entries, iter); release_map_entry(entry); if(FAILED(hres)) diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 21f09474fee..c5d9c47e63c 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -114,6 +114,9 @@ DEFINE_EXPECT(testobj_newenum); DEFINE_EXPECT(testobj_getidfail_d); DEFINE_EXPECT(testobj_tolocalestr_d); DEFINE_EXPECT(testobj_tolocalestr_i); +DEFINE_EXPECT(test_caller_get); +DEFINE_EXPECT(test_caller_null); +DEFINE_EXPECT(test_caller_obj); DEFINE_EXPECT(testdestrobj); DEFINE_EXPECT(enumvariant_next_0); DEFINE_EXPECT(enumvariant_next_1); @@ -333,6 +336,44 @@ static IEnumVARIANTVtbl testEnumVARIANTVtbl = {
static IEnumVARIANT testEnumVARIANT = { &testEnumVARIANTVtbl };
+static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid)) { + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid)); + *ppv = NULL; + return E_NOTIMPL; +} + +static ULONG WINAPI sp_AddRef(IServiceProvider *iface) +{ + return 2; +} + +static ULONG WINAPI sp_Release(IServiceProvider *iface) +{ + return 1; +} + +static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv) +{ + ok(0, "unexpected call %s\n", wine_dbgstr_guid(guidService)); + *ppv = NULL; + return E_NOTIMPL; +} + +static const IServiceProviderVtbl sp_vtbl = { + sp_QueryInterface, + sp_AddRef, + sp_Release, + sp_QueryService +}; + +static IServiceProvider sp_obj = { &sp_vtbl }; + static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -629,6 +670,61 @@ static IDispatchExVtbl testObjVtbl = {
static IDispatchEx testObj = { &testObjVtbl };
+static HRESULT WINAPI testcallerobj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(id == DISPID_VALUE, "id = %ld\n", id); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + if(wFlags == DISPATCH_PROPERTYGET) { + CHECK_EXPECT(test_caller_get); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pei != NULL, "pei == NULL\n"); + ok(pspCaller != NULL, "pspCaller == NULL\n"); + ok(pspCaller != &sp_obj, "pspCaller == sp_obj\n"); + V_VT(pvarRes) = VT_DISPATCH; + V_DISPATCH(pvarRes) = (IDispatch*)iface; + }else if(pspCaller) { + CHECK_EXPECT(test_caller_obj); + ok(wFlags == DISPATCH_METHOD, "wFlags = %04x\n", wFlags); + ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n"); + ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pspCaller == &sp_obj, "pspCaller != sp_obj\n"); + V_VT(pvarRes) = VT_I4; + V_I4(pvarRes) = 137; + }else { + CHECK_EXPECT(test_caller_null); + ok(wFlags == DISPATCH_METHOD, "wFlags = %04x\n", wFlags); + ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n"); + ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs); + V_VT(pvarRes) = VT_I4; + V_I4(pvarRes) = 42; + } + return S_OK; +} + +static IDispatchExVtbl testcallerobj_vtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + DispatchEx_GetDispID, + testcallerobj_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx testcallerobj = { &testcallerobj_vtbl }; + static LONG test_destr_ref;
static ULONG WINAPI testDestrObj_AddRef(IDispatchEx *iface) @@ -3214,6 +3310,7 @@ static void test_script_exprs(void)
static void test_invokeex(void) { + static DISPID propput_dispid = DISPID_PROPERTYPUT; DISPPARAMS dp = {NULL}, dp_max = {NULL}; DISPID func_id, max_id, prop_id; IActiveScript *script; @@ -3442,6 +3539,52 @@ static void test_invokeex(void)
IDispatchEx_Release(dispex); IActiveScript_Release(script); + + /* test InvokeEx with host prop and custom caller */ + hres = parse_script_expr(L"var o = {}; o", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + + hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres); + VariantClear(&v); + + str = SysAllocString(L"caller"); + hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &func_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + + SET_EXPECT(test_caller_get); + dp.cArgs = dp.cNamedArgs = 1; + dp.rgvarg = &arg; + dp.rgdispidNamedArgs = &propput_dispid; + V_VT(&arg) = VT_DISPATCH; + V_DISPATCH(&arg) = (IDispatch*)&testcallerobj; + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + todo_wine + CHECK_CALLED(test_caller_get); + + SET_EXPECT(test_caller_null); + dp.cArgs = dp.cNamedArgs = 0; + dp.rgvarg = NULL; + dp.rgdispidNamedArgs = NULL; + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 42, "V_I4(v) = %s\n", wine_dbgstr_variant(&v)); + CHECK_CALLED(test_caller_null); + V_VT(&v) = VT_EMPTY; + + SET_EXPECT(test_caller_obj); + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, &sp_obj); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 137, "V_I4(v) = %s\n", wine_dbgstr_variant(&v)); + CHECK_CALLED(test_caller_obj); + + IDispatchEx_Release(dispex); + IActiveScript_Release(script); }
static void test_destructors(void)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Add a bunch of tests along the way which verify existing behavior is mostly correct. --- dlls/mshtml/htmlwindow.c | 5 ++ dlls/mshtml/tests/dom.c | 114 +++++++++++++++++++++++++++++- dlls/mshtml/tests/events.c | 139 +++++++++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index f013ba20d1c..c4c6a99f5f3 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2038,6 +2038,11 @@ static HRESULT WINAPI HTMLWindow5_get_XMLHttpRequest(IHTMLWindow5 *iface, VARIAN
TRACE("(%p)->(%p)\n", This, p);
+ if(This->outer_window->readystate == READYSTATE_UNINITIALIZED) { + V_VT(p) = VT_EMPTY; + return S_OK; + } + if(!window->xhr_factory) { HRESULT hres;
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index dc236a27f1c..2efbbbf513c 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11800,12 +11800,23 @@ static void test_quirks_mode(void)
static void test_document_mode_lock(void) { + IHTMLOptionElementFactory *option, *option2; + IHTMLDocument2 *doc, *doc_node, *doc_node2; + IHTMLImageElementFactory *image, *image2; + IOmNavigator *navigator, *navigator2; + IHTMLLocation *location, *location2; + IHTMLPerformance *perf, *perf2; + IOmHistory *history, *history2; + IHTMLScreen *screen, *screen2; IEventTarget *event_target; IPersistStreamInit *init; - IHTMLDocument2 *doc; + IHTMLWindow7 *window7; + IHTMLWindow5 *window5; + IHTMLWindow2 *window; IStream *stream; HRESULT hres; HGLOBAL mem; + VARIANT var; SIZE_T len; MSG msg;
@@ -11818,6 +11829,49 @@ static void test_document_mode_lock(void) ok(hres == E_NOINTERFACE, "QueryInterface(IID_IEventTarget) returned %08lx.\n", hres); ok(event_target == NULL, "event_target != NULL\n");
+ hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_location(window, &location); + ok(hres == S_OK, "get_location failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_navigator(window, &navigator); + ok(hres == S_OK, "get_navigator failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_history(window, &history); + ok(hres == S_OK, "get_history failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_screen(window, &screen); + ok(hres == S_OK, "get_screen failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_Image(window, &image); + ok(hres == S_OK, "get_image failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_Option(window, &option); + ok(hres == S_OK, "get_option failed: %08lx\n", hres); + + V_VT(&var) = VT_NULL; + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + ok(hres == S_OK, "Could not get IHTMLWindow5: %08lx\n", hres); + hres = IHTMLWindow5_get_XMLHttpRequest(window5, &var); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08lx\n", hres); + ok(V_VT(&var) == VT_EMPTY, "V_VT(XMLHttpRequest) = %d\n", V_VT(&var)); + IHTMLWindow5_Release(window5); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + hres = IHTMLWindow7_get_performance(window7, &var); + ok(hres == S_OK, "get_performance failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(performance) = %d\n", V_VT(&var)); + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLPerformance, (void**)&perf); + ok(hres == S_OK, "Could not get IHTMLPerformance: %08lx\n", hres); + IHTMLWindow7_Release(window7); + IHTMLWindow2_Release(window); + VariantClear(&var); + len = strlen(doc_blank_ie9); mem = GlobalAlloc(0, len); memcpy(mem, doc_blank_ie9, len); @@ -11844,6 +11898,64 @@ static void test_document_mode_lock(void) ok(event_target != NULL, "event_target == NULL\n"); IEventTarget_Release(event_target);
+ hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc_node2); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + ok(doc_node != doc_node2, "doc_node == doc_node2\n"); + IHTMLDocument2_Release(doc_node2); + IHTMLDocument2_Release(doc_node); + + hres = IHTMLWindow2_get_location(window, &location2); + ok(hres == S_OK, "get_location failed: %08lx\n", hres); + todo_wine + ok(location == location2, "location != location2\n"); + IHTMLLocation_Release(location2); + IHTMLLocation_Release(location); + + hres = IHTMLWindow2_get_navigator(window, &navigator2); + ok(hres == S_OK, "get_navigator failed: %08lx\n", hres); + ok(navigator != navigator2, "navigator == navigator2\n"); + IOmNavigator_Release(navigator2); + IOmNavigator_Release(navigator); + + hres = IHTMLWindow2_get_history(window, &history2); + ok(hres == S_OK, "get_history failed: %08lx\n", hres); + ok(history != history2, "history == history2\n"); + IOmHistory_Release(history2); + IOmHistory_Release(history); + + hres = IHTMLWindow2_get_screen(window, &screen2); + ok(hres == S_OK, "get_screen failed: %08lx\n", hres); + ok(screen != screen2, "screen == screen2\n"); + IHTMLScreen_Release(screen2); + IHTMLScreen_Release(screen); + + hres = IHTMLWindow2_get_Image(window, &image2); + ok(hres == S_OK, "get_image failed: %08lx\n", hres); + ok(image != image2, "image == image2\n"); + IHTMLImageElementFactory_Release(image2); + IHTMLImageElementFactory_Release(image); + + hres = IHTMLWindow2_get_Option(window, &option2); + ok(hres == S_OK, "get_option failed: %08lx\n", hres); + ok(option != option2, "option == option2\n"); + IHTMLOptionElementFactory_Release(option2); + IHTMLOptionElementFactory_Release(option); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + hres = IHTMLWindow7_get_performance(window7, &var); + ok(hres == S_OK, "get_performance failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(performance) = %d\n", V_VT(&var)); + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLPerformance, (void**)&perf2); + ok(hres == S_OK, "Could not get IHTMLPerformance: %08lx\n", hres); + ok(perf != perf2, "perf == perf2\n"); + IHTMLWindow7_Release(window7); + IHTMLWindow2_Release(window); + VariantClear(&var); + set_client_site(doc, FALSE); IHTMLDocument2_Release(doc); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 30b6d8799b6..196ab3160a7 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3135,9 +3135,22 @@ static void test_iframe_connections(IHTMLDocument2 *doc) static void test_doc_obj(IHTMLDocument2 *doc) { DISPID dispid, import_node_id, has_own_prop_id; + IHTMLOptionElementFactory *option, *option2; + IHTMLImageElementFactory *image, *image2; + IHTMLXMLHttpRequestFactory *xhr, *xhr2; + IHTMLDocument2 *doc_node, *doc_node2; + IOmNavigator *navigator, *navigator2; + IHTMLLocation *location, *location2; int orig_doc_mode = document_mode; + IHTMLStorage *storage, *storage2; + IHTMLPerformance *perf, *perf2; + IOmHistory *history, *history2; + IHTMLScreen *screen, *screen2; IEventTarget *event_target; DISPPARAMS dp = { 0 }; + IHTMLWindow7 *window7; + IHTMLWindow6 *window6; + IHTMLWindow5 *window5; IDispatchEx *dispex; IHTMLElement *body; VARIANT res, arg; @@ -3246,6 +3259,54 @@ static void test_doc_obj(IHTMLDocument2 *doc) SysFreeString(V_BSTR(&arg)); }
+ /* test window props during navigation */ + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_location(window, &location); + ok(hres == S_OK, "get_location failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_navigator(window, &navigator); + ok(hres == S_OK, "get_navigator failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_history(window, &history); + ok(hres == S_OK, "get_history failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_screen(window, &screen); + ok(hres == S_OK, "get_screen failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_Image(window, &image); + ok(hres == S_OK, "get_image failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_Option(window, &option); + ok(hres == S_OK, "get_option failed: %08lx\n", hres); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + ok(hres == S_OK, "Could not get IHTMLWindow5: %08lx\n", hres); + hres = IHTMLWindow5_get_XMLHttpRequest(window5, &res); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08lx\n", hres); + ok(V_VT(&res) == VT_DISPATCH, "V_VT(XMLHttpRequest) = %d\n", V_VT(&res)); + hres = IDispatch_QueryInterface(V_DISPATCH(&res), &IID_IHTMLXMLHttpRequestFactory, (void**)&xhr); + ok(hres == S_OK, "Could not get IHTMLXMLHttpRequestFactory: %08lx\n", hres); + IHTMLWindow5_Release(window5); + VariantClear(&res); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow6, (void**)&window6); + ok(hres == S_OK, "Could not get IHTMLWindow6: %08lx\n", hres); + hres = IHTMLWindow6_get_sessionStorage(window6, &storage); + ok(hres == S_OK, "get_sessionStorage failed: %08lx\n", hres); + IHTMLWindow6_Release(window6); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + hres = IHTMLWindow7_get_performance(window7, &res); + ok(hres == S_OK, "get_performance failed: %08lx\n", hres); + ok(V_VT(&res) == VT_DISPATCH, "V_VT(performance) = %d\n", V_VT(&res)); + hres = IDispatch_QueryInterface(V_DISPATCH(&res), &IID_IHTMLPerformance, (void**)&perf); + ok(hres == S_OK, "Could not get IHTMLPerformance: %08lx\n", hres); + IHTMLWindow7_Release(window7); + VariantClear(&res); + /* Navigate to a different document mode page, checking using the same doc obj. Test that it breaks COM rules, since IEventTarget is conditionally exposed. All the events registered on the old doc node are also removed. @@ -3286,6 +3347,84 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(hres == S_OK, "GetIDsOfNames(importNode) returned: %08lx\n", hres); ok(dispid != import_node_id, "importNode on new doc node == old created importNode\n"); } + + hres = IHTMLWindow2_get_document(window, &doc_node2); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + ok(doc_node != doc_node2, "doc_node == doc_node2\n"); + IHTMLDocument2_Release(doc_node2); + IHTMLDocument2_Release(doc_node); + + hres = IHTMLWindow2_get_location(window, &location2); + ok(hres == S_OK, "get_location failed: %08lx\n", hres); + todo_wine + ok(location == location2, "location != location2\n"); + IHTMLLocation_Release(location2); + IHTMLLocation_Release(location); + + hres = IHTMLWindow2_get_navigator(window, &navigator2); + ok(hres == S_OK, "get_navigator failed: %08lx\n", hres); + ok(navigator != navigator2, "navigator == navigator2\n"); + IOmNavigator_Release(navigator2); + IOmNavigator_Release(navigator); + + hres = IHTMLWindow2_get_history(window, &history2); + ok(hres == S_OK, "get_history failed: %08lx\n", hres); + ok(history != history2, "history == history2\n"); + IOmHistory_Release(history2); + IOmHistory_Release(history); + + hres = IHTMLWindow2_get_screen(window, &screen2); + ok(hres == S_OK, "get_screen failed: %08lx\n", hres); + ok(screen != screen2, "screen == screen2\n"); + IHTMLScreen_Release(screen2); + IHTMLScreen_Release(screen); + + hres = IHTMLWindow2_get_Image(window, &image2); + ok(hres == S_OK, "get_image failed: %08lx\n", hres); + ok(image != image2, "image == image2\n"); + IHTMLImageElementFactory_Release(image2); + IHTMLImageElementFactory_Release(image); + + hres = IHTMLWindow2_get_Option(window, &option2); + ok(hres == S_OK, "get_option failed: %08lx\n", hres); + ok(option != option2, "option == option2\n"); + IHTMLOptionElementFactory_Release(option2); + IHTMLOptionElementFactory_Release(option); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + ok(hres == S_OK, "Could not get IHTMLWindow5: %08lx\n", hres); + hres = IHTMLWindow5_get_XMLHttpRequest(window5, &res); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08lx\n", hres); + ok(V_VT(&res) == VT_DISPATCH, "V_VT(XMLHttpRequest) = %d\n", V_VT(&res)); + hres = IDispatch_QueryInterface(V_DISPATCH(&res), &IID_IHTMLXMLHttpRequestFactory, (void**)&xhr2); + ok(hres == S_OK, "Could not get IHTMLXMLHttpRequestFactory: %08lx\n", hres); + ok(xhr != xhr2, "xhr == xhr2\n"); + IHTMLXMLHttpRequestFactory_Release(xhr2); + IHTMLXMLHttpRequestFactory_Release(xhr); + IHTMLWindow5_Release(window5); + VariantClear(&res); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow6, (void**)&window6); + ok(hres == S_OK, "Could not get IHTMLWindow6: %08lx\n", hres); + hres = IHTMLWindow6_get_sessionStorage(window6, &storage2); + ok(hres == S_OK, "get_sessionStorage failed: %08lx\n", hres); + ok(storage != storage2, "storage == storage2\n"); + IHTMLStorage_Release(storage2); + IHTMLStorage_Release(storage); + IHTMLWindow6_Release(window6); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow7, (void**)&window7); + ok(hres == S_OK, "Could not get IHTMLWindow7: %08lx\n", hres); + hres = IHTMLWindow7_get_performance(window7, &res); + ok(hres == S_OK, "get_performance failed: %08lx\n", hres); + ok(V_VT(&res) == VT_DISPATCH, "V_VT(performance) = %d\n", V_VT(&res)); + hres = IDispatch_QueryInterface(V_DISPATCH(&res), &IID_IHTMLPerformance, (void**)&perf2); + ok(hres == S_OK, "Could not get IHTMLPerformance: %08lx\n", hres); + ok(perf != perf2, "perf == perf2\n"); + IHTMLPerformance_Release(perf2); + IHTMLPerformance_Release(perf); + IHTMLWindow7_Release(window7); + VariantClear(&res); }
static void test_create_event(IHTMLDocument2 *doc)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Even in IE9+ modes, it's still a non-JS object.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 31 ++++++++++++++----------------- dlls/mshtml/htmlwindow.c | 16 ++++++++-------- dlls/mshtml/mshtml_private.h | 7 +++---- dlls/mshtml/tests/dom.c | 1 - dlls/mshtml/tests/events.c | 1 - 5 files changed, 25 insertions(+), 31 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 066ebb4f5e6..5c31ee02e04 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -38,18 +38,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
static HRESULT get_url(HTMLLocation *This, const WCHAR **ret) { - if(!This->window || !This->window->base.outer_window || !This->window->base.outer_window->url) + if(!This->window || !This->window->url) *ret = L"about:blank"; else - *ret = This->window->base.outer_window->url; + *ret = This->window->url; return S_OK; }
static IUri *get_uri(HTMLLocation *This) { - if(!This->window || !This->window->base.outer_window) - return NULL; - return This->window->base.outer_window->uri; + return This->window ? This->window->uri : NULL; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) @@ -165,12 +163,12 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->window || !This->window->base.outer_window) { + if(!This->window) { FIXME("No window available\n"); return E_FAIL; }
- return navigate_url(This->window->base.outer_window, v, This->window->base.outer_window->uri, BINDING_NAVIGATED); + return navigate_url(This->window, v, This->window->uri, BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) @@ -523,7 +521,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->window || !This->window->base.outer_window) { + if(!This->window) { FIXME("No window available\n"); return E_FAIL; } @@ -536,7 +534,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) memcpy(hash + 1, v, size - sizeof(WCHAR)); }
- hres = navigate_url(This->window->base.outer_window, hash, This->window->base.outer_window->uri, BINDING_NAVIGATED); + hres = navigate_url(This->window, hash, This->window->uri, BINDING_NAVIGATED);
if(hash != v) free(hash); @@ -585,12 +583,12 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla }
/* reload is supposed to fail if called from a script with different origin, but IE doesn't care */ - if(!is_main_content_window(This->window->base.outer_window)) { + if(!is_main_content_window(This->window)) { FIXME("Unsupported on iframe\n"); return E_NOTIMPL; }
- return reload_page(This->window->base.outer_window); + return reload_page(This->window); }
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) @@ -599,13 +597,12 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
- if(!This->window || !This->window->base.outer_window) { + if(!This->window) { FIXME("No window available\n"); return E_FAIL; }
- return navigate_url(This->window->base.outer_window, bstr, This->window->base.outer_window->uri, - BINDING_NAVIGATED|BINDING_REPLACE); + return navigate_url(This->window, bstr, This->window->uri, BINDING_NAVIGATED | BINDING_REPLACE); }
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) @@ -659,14 +656,14 @@ static const tid_t HTMLLocation_iface_tids[] = { 0 }; static dispex_static_data_t HTMLLocation_dispex = { - L"Object", + L"Location", NULL, DispHTMLLocation_tid, HTMLLocation_iface_tids };
-HRESULT HTMLLocation_Create(HTMLInnerWindow *window, HTMLLocation **ret) +HRESULT HTMLLocation_Create(HTMLOuterWindow *window, HTMLLocation **ret) { HTMLLocation *location;
@@ -679,7 +676,7 @@ HRESULT HTMLLocation_Create(HTMLInnerWindow *window, HTMLLocation **ret) location->window = window;
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex, - dispex_compat_mode(&window->event_target.dispex)); + COMPAT_MODE_QUIRKS);
*ret = location; return S_OK; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c4c6a99f5f3..9f623e77f77 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -67,7 +67,7 @@ static inline BOOL is_outer_window(HTMLWindow *window) return &window->outer_window->base == window; }
-static HRESULT get_location(HTMLInnerWindow *This, HTMLLocation **ret) +static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret) { if(!This->location) { HRESULT hres; @@ -237,6 +237,11 @@ static void release_outer_window(HTMLOuterWindow *This) if(This->base.inner_window) detach_inner_window(This->base.inner_window);
+ if(This->location) { + This->location->window = NULL; + IHTMLLocation_Release(&This->location->IHTMLLocation_iface); + } + if(This->frame_element) This->frame_element->content_window = NULL;
@@ -269,11 +274,6 @@ static void release_inner_window(HTMLInnerWindow *This) free(This->global_props[i].name); free(This->global_props);
- if(This->location) { - This->location->window = NULL; - IHTMLLocation_Release(&This->location->IHTMLLocation_iface); - } - if(This->image_factory) { This->image_factory->window = NULL; IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface); @@ -809,7 +809,7 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio
TRACE("(%p)->(%p)\n", This, p);
- hres = get_location(This->inner_window, &location); + hres = get_location(This->outer_window, &location); if(FAILED(hres)) return hres;
@@ -3922,7 +3922,7 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
- hres = get_location(This, &location); + hres = get_location(This->base.outer_window, &location); if(FAILED(hres)) return hres;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 870ba14c8b4..1ce25d5c862 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -493,7 +493,7 @@ struct HTMLLocation {
LONG ref;
- HTMLInnerWindow *window; + HTMLOuterWindow *window; };
typedef struct { @@ -576,6 +576,7 @@ struct HTMLOuterWindow { unsigned readystate_pending;
HTMLInnerWindow *pending_window; + HTMLLocation *location; IMoniker *mon; IUri *uri; IUri *uri_nofrag; @@ -619,8 +620,6 @@ struct HTMLInnerWindow {
LONG task_magic;
- HTMLLocation *location; - IMoniker *mon; nsChannelBSC *bscallback; struct list bindings; @@ -994,7 +993,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**) DECLSPEC_HIDDEN; HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**) DECLSPEC_HIDDEN; HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**) DECLSPEC_HIDDEN; HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**) DECLSPEC_HIDDEN; -HRESULT HTMLLocation_Create(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN; +HRESULT HTMLLocation_Create(HTMLOuterWindow*,HTMLLocation**) DECLSPEC_HIDDEN; HRESULT create_navigator(compat_mode_t,IOmNavigator**) DECLSPEC_HIDDEN; HRESULT create_html_screen(compat_mode_t,IHTMLScreen**) DECLSPEC_HIDDEN; HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 2efbbbf513c..7643388a94f 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11909,7 +11909,6 @@ static void test_document_mode_lock(void)
hres = IHTMLWindow2_get_location(window, &location2); ok(hres == S_OK, "get_location failed: %08lx\n", hres); - todo_wine ok(location == location2, "location != location2\n"); IHTMLLocation_Release(location2); IHTMLLocation_Release(location); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 196ab3160a7..2165410e62d 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3356,7 +3356,6 @@ static void test_doc_obj(IHTMLDocument2 *doc)
hres = IHTMLWindow2_get_location(window, &location2); ok(hres == S_OK, "get_location failed: %08lx\n", hres); - todo_wine ok(location == location2, "location != location2\n"); IHTMLLocation_Release(location2); IHTMLLocation_Release(location);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Gets rid of the issues with the cyclic dependency or detached location.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 80 ++++++------------------------------ dlls/mshtml/htmlwindow.c | 32 ++++----------- dlls/mshtml/mshtml_private.h | 8 +--- 3 files changed, 23 insertions(+), 97 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 5c31ee02e04..d9e458d9c5f 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -36,28 +36,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-static HRESULT get_url(HTMLLocation *This, const WCHAR **ret) +static inline HTMLOuterWindow *get_window(HTMLLocation *This) { - if(!This->window || !This->window->url) - *ret = L"about:blank"; - else - *ret = This->window->url; - return S_OK; + return CONTAINING_RECORD(This, HTMLOuterWindow, location); }
static IUri *get_uri(HTMLLocation *This) { - return This->window ? This->window->uri : NULL; + return get_window(This)->uri; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) { - const WCHAR *doc_url; - HRESULT hres; - - hres = get_url(This, &doc_url); - if(FAILED(hres)) - return hres; + const WCHAR *doc_url = get_window(This)->url ? get_window(This)->url : L"about:blank";
if(!InternetCrackUrlW(doc_url, 0, 0, url)) { FIXME("InternetCrackUrlW failed: 0x%08lx\n", GetLastError()); @@ -102,28 +93,13 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; + return IHTMLWindow2_AddRef(&get_window(This)->base.IHTMLWindow2_iface); }
static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - if(This->window) - This->window->location = NULL; - release_dispex(&This->dispex); - free(This); - } - - return ref; + return IHTMLWindow2_Release(&get_window(This)->base.IHTMLWindow2_iface); }
static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo) @@ -163,12 +139,7 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->window) { - FIXME("No window available\n"); - return E_FAIL; - } - - return navigate_url(This->window, v, This->window->uri, BINDING_NAVIGATED); + return navigate_url(get_window(This), v, get_uri(This), BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) @@ -521,11 +492,6 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->window) { - FIXME("No window available\n"); - return E_FAIL; - } - if(hash[0] != '#') { unsigned size = (1 /* # */ + wcslen(v) + 1) * sizeof(WCHAR); if(!(hash = malloc(size))) @@ -534,7 +500,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) memcpy(hash + 1, v, size - sizeof(WCHAR)); }
- hres = navigate_url(This->window, hash, This->window->uri, BINDING_NAVIGATED); + hres = navigate_url(get_window(This), hash, get_uri(This), BINDING_NAVIGATED);
if(hash != v) free(hash); @@ -577,18 +543,13 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla
TRACE("(%p)->(%x)\n", This, flag);
- if(!This->window) { - FIXME("No window available\n"); - return E_FAIL; - } - /* reload is supposed to fail if called from a script with different origin, but IE doesn't care */ - if(!is_main_content_window(This->window)) { + if(!is_main_content_window(get_window(This))) { FIXME("Unsupported on iframe\n"); return E_NOTIMPL; }
- return reload_page(This->window); + return reload_page(get_window(This)); }
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) @@ -597,12 +558,7 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
- if(!This->window) { - FIXME("No window available\n"); - return E_FAIL; - } - - return navigate_url(This->window, bstr, This->window->uri, BINDING_NAVIGATED | BINDING_REPLACE); + return navigate_url(get_window(This), bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); }
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) @@ -662,22 +618,10 @@ static dispex_static_data_t HTMLLocation_dispex = { HTMLLocation_iface_tids };
- -HRESULT HTMLLocation_Create(HTMLOuterWindow *window, HTMLLocation **ret) +void HTMLLocation_Init(HTMLLocation *location) { - HTMLLocation *location; - - location = malloc(sizeof(*location)); - if(!location) - return E_OUTOFMEMORY; - location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; - location->ref = 1; - location->window = window;
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex, COMPAT_MODE_QUIRKS); - - *ret = location; - return S_OK; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 9f623e77f77..d32b6743e9b 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -67,19 +67,13 @@ static inline BOOL is_outer_window(HTMLWindow *window) return &window->outer_window->base == window; }
-static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret) +static void get_location(HTMLOuterWindow *This, HTMLLocation **ret) { - if(!This->location) { - HRESULT hres; + if(!This->location.dispex.outer) + HTMLLocation_Init(&This->location);
- hres = HTMLLocation_Create(This, &This->location); - if(FAILED(hres)) - return hres; - } - - IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface); - *ret = This->location; - return S_OK; + IHTMLLocation_AddRef(&This->location.IHTMLLocation_iface); + *ret = &This->location; }
void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret) @@ -237,10 +231,8 @@ static void release_outer_window(HTMLOuterWindow *This) if(This->base.inner_window) detach_inner_window(This->base.inner_window);
- if(This->location) { - This->location->window = NULL; - IHTMLLocation_Release(&This->location->IHTMLLocation_iface); - } + if(This->location.dispex.outer) + release_dispex(&This->location.dispex);
if(This->frame_element) This->frame_element->content_window = NULL; @@ -805,14 +797,10 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio { HTMLWindow *This = impl_from_IHTMLWindow2(iface); HTMLLocation *location; - HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
- hres = get_location(This->outer_window, &location); - if(FAILED(hres)) - return hres; - + get_location(This->outer_window, &location); *p = &location->IHTMLLocation_iface; return S_OK; } @@ -3922,9 +3910,7 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
- hres = get_location(This->base.outer_window, &location); - if(FAILED(hres)) - return hres; + get_location(This->base.outer_window, &location);
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller); IHTMLLocation_Release(&location->IHTMLLocation_iface); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 1ce25d5c862..bec982a75fc 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -490,10 +490,6 @@ typedef struct { struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; - - LONG ref; - - HTMLOuterWindow *window; };
typedef struct { @@ -576,7 +572,7 @@ struct HTMLOuterWindow { unsigned readystate_pending;
HTMLInnerWindow *pending_window; - HTMLLocation *location; + HTMLLocation location; IMoniker *mon; IUri *uri; IUri *uri_nofrag; @@ -993,7 +989,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**) DECLSPEC_HIDDEN; HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**) DECLSPEC_HIDDEN; HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**) DECLSPEC_HIDDEN; HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**) DECLSPEC_HIDDEN; -HRESULT HTMLLocation_Create(HTMLOuterWindow*,HTMLLocation**) DECLSPEC_HIDDEN; +void HTMLLocation_Init(HTMLLocation*) DECLSPEC_HIDDEN; HRESULT create_navigator(compat_mode_t,IOmNavigator**) DECLSPEC_HIDDEN; HRESULT create_html_screen(compat_mode_t,IHTMLScreen**) DECLSPEC_HIDDEN; HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**) DECLSPEC_HIDDEN;
Jacek Caban (@jacek) commented about dlls/jscript/jscript.h:
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; HRESULT disp_call_name(script_ctx_t*,IDispatch*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; -HRESULT disp_call_value(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; +HRESULT disp_call_value(script_ctx_t*,IDispatch*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*,IServiceProvider*) DECLSPEC_HIDDEN;
It seems that only a few cases in dispex.c need to explicitly pass caller, while it's obscuring all other calls. We could use make it an inline helper that would pass ctx caller to an extended version.
Jacek Caban (@jacek) commented about dlls/mshtml/htmlwindow.c:
free(This->global_props[i].name); free(This->global_props);
- if(This->location) {
This->location->window = NULL;
IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
- }
With this patch, if a script modifies the object (for example by adding a new property), the change will be still visible after navigation. That doesn't seem right.
On Tue Jan 31 12:44:53 2023 +0000, Jacek Caban wrote:
It seems that only a few cases in dispex.c need to explicitly pass caller, while it's obscuring all other calls. We could use make it an inline helper that would pass ctx caller to an extended version.
I agree, I wanted to do that initially (also because fewer changes), but for some reason I thought it would be less elegant/more ugly or something.