From 80a1a2f135f493d0d5b5e94b461d2751ef8ff9d5 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 14 Aug 2007 22:36:56 +0200 Subject: [PATCH] mshtml: Make window.external visible for JavaScript code. --- dlls/mshtml/htmlwindow.c | 102 ++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 3 + dlls/mshtml/nsembed.c | 40 ++++++++++ dlls/mshtml/nsiface.idl | 170 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 314 insertions(+), 1 deletion(-) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 1acb6dbd442..369a09c52fb 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -755,6 +755,108 @@ static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = { HTMLWindow2_get_external }; +static const char wineConfig_func[] = +"window.__defineGetter__(\"external\",function() {\n" +" return window.__wineWindow__.external;\n" +"});\n" +"window.__wineWindow__ = wineWindow;\n"; + +static void astr_to_nswstr(const char *str, nsAString *nsstr) +{ + LPWSTR wstr; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + wstr = mshtml_alloc(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, len); + + nsAString_Init(nsstr, wstr); + + mshtml_free(wstr); +} + +static nsresult call_js_func(nsIScriptContainer *script_container, nsISupports *target, + const char *name, const char *body, + PRUint32 argc, const char **arg_names, nsIArray *argv) +{ + nsACString name_str; + nsAString body_str; + JSObject func_obj, jsglobal; + nsIVariant *jsret; + nsresult nsres; + + nsres = nsIScriptContainer_GetGlobalObject(script_container, &jsglobal); + if(NS_FAILED(nsres)) + ERR("GetGlobalObject: %08x\n", nsres); + + nsACString_Init(&name_str, name); + astr_to_nswstr(body, &body_str); + + nsres = nsIScriptContainer_CompileFunction(script_container, jsglobal, &name_str, argc, arg_names, + &body_str, NULL, 1, FALSE, &func_obj); + + nsACString_Finish(&name_str); + nsAString_Finish(&body_str); + + if(NS_FAILED(nsres)) { + ERR("CompileFunction failed: %08x\n", nsres); + return nsres; + } + + nsres = nsIScriptContainer_CallFunction(script_container, target, jsglobal, func_obj, argv, &jsret); + + nsIScriptContainer_DropScriptObject(script_container, func_obj); + nsIScriptContainer_DropScriptObject(script_container, jsglobal); + if(NS_FAILED(nsres)) { + ERR("CallFunction failed: %08x\n", nsres); + return nsres; + } + + nsIVariant_Release(jsret); + return NS_OK; +} + +void setup_nswindow(HTMLWindow *This) +{ + nsIScriptContainer *script_container; + nsIDOMWindow *nswindow; + nsIDOMDocument *domdoc; + nsIWritableVariant *nsvar; + nsIMutableArray *argv; + nsresult nsres; + + static const char *args[] = {"wineWindow"}; + + TRACE("(%p)\n", This); + + nsIWebNavigation_GetDocument(This->doc->nscontainer->navigation, &domdoc); + nsres = nsIDOMDocument_QueryInterface(domdoc, &IID_nsIScriptContainer, (void**)&script_container); + nsIDOMDocument_Release(domdoc); + if(NS_FAILED(nsres)) { + TRACE("Could not get nsIDOMScriptContainer: %08x\n", nsres); + return; + } + + nsIWebBrowser_GetContentDOMWindow(This->doc->nscontainer->webbrowser, &nswindow); + + nsvar = create_nsvariant(); + nsres = nsIWritableVariant_SetAsInterface(nsvar, &IID_IDispatch, HTMLWINDOW2(This)); + if(NS_FAILED(nsres)) + ERR("SetAsInterface failed: %08x\n", nsres); + + argv = create_nsarray(); + nsres = nsIMutableArray_AppendElement(argv, (nsISupports*)nsvar, FALSE); + nsIWritableVariant_Release(nsvar); + if(NS_FAILED(nsres)) + ERR("AppendElement failed: %08x\n", nsres); + + call_js_func(script_container, (nsISupports*)nswindow/*HTMLWINDOW2(This)*/, "wineConfig", + wineConfig_func, 1, args, (nsIArray*)argv); + + nsIMutableArray_Release(argv); + nsIScriptContainer_Release(script_container); +} + HTMLWindow *HTMLWindow_Create(HTMLDocument *doc) { HTMLWindow *ret = mshtml_alloc(sizeof(HTMLWindow)); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index bf57b7ed76d..d96c0fce7d9 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -339,6 +339,7 @@ HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**); HTMLWindow *HTMLWindow_Create(HTMLDocument*); HTMLWindow *nswindow_to_window(const nsIDOMWindow*); +void setup_nswindow(HTMLWindow*); void HTMLDocument_HTMLDocument3_Init(HTMLDocument*); void HTMLDocument_Persist_Init(HTMLDocument*); @@ -388,6 +389,8 @@ void nsAString_Finish(nsAString*); nsIInputStream *create_nsstream(const char*,PRInt32); nsICommandParams *create_nscommand_params(void); +nsIMutableArray *create_nsarray(void); +nsIWritableVariant *create_nsvariant(void); void nsnode_to_nsstring(nsIDOMNode*,nsAString*); nsIController *get_editor_controller(NSContainer*); void init_nsevents(NSContainer*); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 0697d4dee88..0dfdf0ebd27 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1" #define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html" #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1" +#define NS_ARRAY_CONTRACTID "@mozilla.org/array;1" +#define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1" #define APPSTARTUP_TOPIC "app-startup" @@ -466,6 +468,44 @@ nsIInputStream *create_nsstream(const char *data, PRInt32 data_len) return (nsIInputStream*)ret; } +nsIMutableArray *create_nsarray(void) +{ + nsIMutableArray *ret; + nsresult nsres; + + if(!pCompMgr) + return NULL; + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, + NS_ARRAY_CONTRACTID, NULL, &IID_nsIMutableArray, + (void**)&ret); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIArray: %08x\n", nsres); + return NULL; + } + + return ret; +} + +nsIWritableVariant *create_nsvariant(void) +{ + nsIWritableVariant *ret; + nsresult nsres; + + if(!pCompMgr) + return NULL; + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, + NS_VARIANT_CONTRACTID, NULL, &IID_nsIWritableVariant, + (void**)&ret); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIWritableVariant: %08x\n", nsres); + return NULL; + } + + return ret; +} + nsICommandParams *create_nscommand_params(void) { nsICommandParams *ret = NULL; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 78e030bc5c8..f402b36be06 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -31,6 +31,7 @@ import "wtypes.idl"; typedef HRESULT nsresult; typedef ULONG nsrefcnt; +typedef IID nsID; typedef IID nsIID; typedef nsIID nsCID; typedef REFIID nsIIDRef; @@ -87,7 +88,6 @@ interface nsISupports /* Currently we don't need a full declaration of these interfaces */ typedef nsISupports nsISHistory; -typedef nsISupports nsISimpleEnumerator; typedef nsISupports nsIWidget; typedef nsISupports nsIDOMAbstractView; typedef nsISupports nsIHttpHeaderVisitor; @@ -111,6 +111,8 @@ typedef nsISupports nsIDOMCSSValue; typedef nsISupports nsIDOMCSSRule; typedef nsISupports nsIPrintSession; typedef nsISupports nsIControllerCommandTable; +typedef nsISupports nsIPrincipal; +typedef nsISupports nsIAtom; [ object, @@ -207,6 +209,149 @@ interface nsIInterfaceRequestor : nsISupports [ object, + uuid(d1899240-f9d2-11d2-bdd6-000064657374) + /* FROZEN */ +] +interface nsISimpleEnumerator : nsISupports +{ + nsresult HasMoreElements(PRBool *_retval); + nsresult GetNext(nsISupports **_retval); +} + +[ + object, + uuid(114744d9-c369-456e-b55a-52fe52880d2d) + /* NOT_FROZEN */ +] +interface nsIArray : nsISupports +{ + nsresult GetLength(PRUint32 *aLength); + nsresult QueryElementAt(PRUint32 index, const nsIID *uuid, void **result); + nsresult IndexOf(PRUint32 startIndex, nsISupports *element, PRUint32 *_retval); + nsresult Enumerate(nsISimpleEnumerator **_retval); +} + +[ + object, + uuid(af059da0-c85b-40ec-af07-ae4bfdc192cc) + /* NOT_FROZEN */ +] +interface nsIMutableArray : nsIArray +{ + nsresult AppendElement(nsISupports *element, PRBool weak); + nsresult RemoveElementAt(PRUint32 index); + nsresult InsertElementAt(nsISupports *element, PRUint32 index, PRBool weak); + nsresult Clear(); +} + +[ + object, + uuid(4d12e540-83d7-11d5-90ed-0010a4e73d9a) + /* NOT_FROZEN */ +] +interface nsIVariant : nsISupports +{ + enum nsDataType { + TYPE_INT8, + TYPE_INT16, + TYPE_INT32, + TYPE_INT64, + TYPE_UINT8, + TYPE_UINT16, + TYPE_UINT32, + TYPE_UINT64, + TYPE_FLOAT, + TYPE_DOUBLE, + TYPE_BOOL, + TYPE_CHAR, + TYPE_WCHAR, + TYPE_VOID, + TYPE_ID, + TYPE_DOMSTRING, + TYPE_CHAR_STR, + TYPE_WCHAR_STR, + TYPE_INTERFACE, + TYPE_INTERFACE_IS, + TYPE_ARRAY, + TYPE_STRING_SIZE_IS, + TYPE_WSTRING_SIZE_IS, + TYPE_UTF8STRING, + TYPE_CSTRING, + TYPE_ASTRING, + TYPE_AMPTY_ARRAY, + TYPE_EMPTY + }; + + nsresult GetDataType(PRUint16 *aDataType); + nsresult GetAsInt8(PRUint8 *_retval); + nsresult GetAsInt16(PRInt16 *_retval); + nsresult GetAsInt32(PRInt32 *_retval); + nsresult GetAsInt64(PRInt64 *_retval); + nsresult GetAsUint8(PRUint8 *_retval); + nsresult GetAsUint16(PRUint16 *_retval); + nsresult GetAsUint32(PRUint32 *_retval); + nsresult GetAsUint64(PRUint64 *_retval); + nsresult GetAsFloat(float *_retval); + nsresult GetAsDouble(double *_retval); + nsresult GetAsBool(PRBool *_retval); + nsresult GetAsChar(char *_retval); + nsresult GetAsWChar(PRUnichar *_retval); + nsresult GetAsID(nsID *retval); + nsresult GetAsAString(nsAString *_retval); + nsresult GetAsDOMString(nsAString *_retval); + nsresult GetAsACString(nsACString *_retval); + nsresult GetAsAUTF8String(nsACString *_retval); + nsresult GetAsString(char **_retval); + nsresult GetAsWString(PRUnichar **_retval); + nsresult GetAsISupports(nsISupports **_retval); + nsresult GetAsInterface(nsIID * *iid, void **iface); + nsresult GetAsArray(PRUint16 *type, nsIID *iid, PRUint32 *count, void **ptr); + nsresult GetAsStringWithSize(PRUint32 *size, char **str); + nsresult GetAsWStringWithSize(PRUint32 *size, PRUnichar **str); +} + +[ + object, + uuid(5586a590-8c82-11d5-90f3-0010a4e73d9a) + /* NOT_FROZEN */ +] +interface nsIWritableVariant : nsIVariant +{ + nsresult GetWritable(PRBool *aWritable); + nsresult SetWritable(PRBool aWritable); + nsresult SetAsInt8(PRUint8 aValue); + nsresult SetAsInt16(PRInt16 aValue); + nsresult SetAsInt32(PRInt32 aValue); + nsresult SetAsInt64(PRInt64 aValue); + nsresult SetAsUint8(PRUint8 aValue); + nsresult SetAsUint16(PRUint16 aValue); + nsresult SetAsUint32(PRUint32 aValue); + nsresult SetAsUint64(PRUint64 aValue); + nsresult SetAsFloat(float aValue); + nsresult SetAsDouble(double aValue); + nsresult SetAsBool(PRBool aValue); + nsresult SetAsChar(char aValue); + nsresult SetAsWChar(PRUnichar aValue); + nsresult SetAsID(const nsID *aValue); + nsresult SetAsAString(const nsAString *aValue); + nsresult SetAsDOMString(const nsAString *aValue); + nsresult SetAsACString(const nsACString *aValue); + nsresult SetAsAUTF8String(const nsACString *aValue); + nsresult SetAsString(const char *aValue); + nsresult SetAsWString(const PRUnichar *aValue); + nsresult SetAsISupports(nsISupports *aValue); + nsresult SetAsInterface(const nsIID *iid, void *iface); + nsresult SetAsArray(PRUint16 type, const nsIID *iid, PRUint32 count, void *ptr); + nsresult SetAsStringWithSize(PRUint32 size, const char *str); + nsresult SetAsWStringWithSize(PRUint32 size, const PRUnichar *str); + nsresult SetAsVoid(); + nsresult SetAsEmpty(); + nsresult SetAsEmptyArray(); + nsresult SetFromVariant(nsIVariant *aValue); +} + +[ + object, uuid(fa9c7f6c-61b3-11d4-9877-00c04fa0cf4a) /* FROZEN */ ] @@ -1709,6 +1854,29 @@ interface nsIContentSerializer : nsISupports nsresult AppendDocumentStart(nsIDOMDocument *aDocument, nsAString *aStr); } +[ + object, + uuid(68b97c56-2289-48ac-a9e1-72c30fd3dba2) +] +interface nsIScriptContainer : nsISupports +{ + typedef void *JSObject; + + nsresult GetContext(void **aContext); + nsresult GetGlobalObject(void **aGlobalObject); + nsresult CompileScript(const PRUnichar *aText, PRInt32 aTextLength, void *aScopeObject, + nsIPrincipal *aPrincipal, const char *aURL, PRUint32 aLineNo, PRUint32 aVersion, void **_retval); + nsresult ExecuteScript(void *aScriptObject, void *aScopeObject, nsAString *aRetVal, PRBool *aIsUndefined); + nsresult CompileFunction(void *aTarget, const nsACString *aName, PRUint32 aArgCount, + const char **aArgArray, const nsAString *aBody, const char *aURL, PRInt32 aLineNo, + PRBool aShared, void* *_retval); + nsresult CallFunction(nsISupports *aTarget, void *aScope, void *aHandler, nsIArray *argv, + nsIVariant **_retval); + nsresult BindEventHandler(nsISupports *aTarget, void *aScope, nsIAtom *aName, void *aHandler); + nsresult HoldScriptObject(void *aObject); + nsresult DropScriptObject(void *aObject); +} + /* * NOTE: * This is a private Wine interface that is implemented by our implementation -- 2.11.4.GIT