gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2007 Google Inc. |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 5 | * use this file except in compliance with the License. You may obtain a copy of |
| 6 | * the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 | * License for the specific language governing permissions and limitations under |
| 14 | * the License. |
| 15 | */ |
| 16 | |
| 17 | /* |
| 18 | * Defines the JavaScript class gwt_external_class, which interface via JNI |
| 19 | * to Java objects. |
| 20 | */ |
| 21 | |
| 22 | #include <jni.h> |
| 23 | #include "JsRootedValue.h" |
| 24 | #include "gwt-jni.h" |
| 25 | #include "ExternalWrapper.h" |
| 26 | #include "Tracer.h" |
| 27 | #include "JsStringWrap.h" |
| 28 | |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 29 | #ifdef ENABLE_TRACING |
| 30 | extern void PrintJSValue(JSContext* cx, jsval val, char* prefix=""); |
| 31 | #else |
| 32 | // Include a null version just to keep from cluttering up call sites. |
| 33 | static inline void PrintJSValue(JSContext* cx, jsval val, char* prefix="") { } |
| 34 | #endif |
| 35 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 36 | // note that this does not use the NS_DEFINE_CID macro because it defines |
| 37 | // the variable as const, which by default has internal linkage. I could |
| 38 | // work around it by putting extern in front of the macro, but that seems |
| 39 | // fragile if the macro changes. |
| 40 | nsCID kGwtExternalCID = GWT_EXTERNAL_FACTORY_CID; |
| 41 | |
| 42 | /* |
| 43 | * definition of JavaScript gwtOnLoad method which maps to the Java |
| 44 | * gwtOnLoad method. |
| 45 | */ |
| 46 | static JSBool gwtOnLoad(JSContext *cx, JSObject *obj, uintN argc, |
| 47 | jsval *argv, jsval *rval) |
| 48 | { |
| 49 | Tracer tracer("gwtOnLoad"); |
gwt.team.jat | d43ad6c | 2007-03-19 22:24:12 +0000 | [diff] [blame] | 50 | tracer.log("context=%08x", unsigned(cx)); |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 51 | JsRootedValue::ContextManager context(cx); |
gwt.team.jat | d43ad6c | 2007-03-19 22:24:12 +0000 | [diff] [blame] | 52 | JsRootedValue::ensureRuntime(cx); |
jat@google.com | e7f61a7 | 2008-12-24 00:45:21 +0000 | [diff] [blame] | 53 | if (argc < 3) { |
| 54 | tracer.setFail("less than 3 args"); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 55 | return JS_FALSE; |
| 56 | } |
| 57 | |
| 58 | JSObject* scriptWindow = 0; |
| 59 | if (argv[0] != JSVAL_NULL && argv[0] != JSVAL_VOID) { |
| 60 | if (!JS_ValueToObject(cx, argv[0], &scriptWindow)) { |
| 61 | tracer.setFail("can't get script window object"); |
| 62 | return JS_FALSE; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | JSString* moduleName = 0; |
| 67 | if (argv[1] != JSVAL_NULL && argv[1] != JSVAL_VOID) { |
| 68 | moduleName = JS_ValueToString(cx, argv[1]); |
| 69 | } |
| 70 | |
scottb@google.com | bd9fe8c | 2008-08-28 22:56:54 +0000 | [diff] [blame] | 71 | JSString* version = 0; |
jat@google.com | e7f61a7 | 2008-12-24 00:45:21 +0000 | [diff] [blame] | 72 | if (argv[2] != JSVAL_NULL && argv[2] != JSVAL_VOID) { |
scottb@google.com | bd9fe8c | 2008-08-28 22:56:54 +0000 | [diff] [blame] | 73 | version = JS_ValueToString(cx, argv[2]); |
| 74 | } |
| 75 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 76 | nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(0); |
| 77 | if (scriptWindow) { |
| 78 | nsCOMPtr<nsIXPConnect> xpConnect = do_GetService(nsIXPConnect::GetCID()); |
| 79 | nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative; |
| 80 | xpConnect->GetWrappedNativeOfJSObject(cx, scriptWindow, |
| 81 | getter_AddRefs(wrappedNative)); |
| 82 | if (wrappedNative) { |
| 83 | nsCOMPtr<nsISupports> native; |
| 84 | wrappedNative->GetNative(getter_AddRefs(native)); |
| 85 | scriptGlobal = do_QueryInterface(native); |
| 86 | } |
| 87 | } |
| 88 | jstring jModuleName(0); |
| 89 | if (moduleName) { |
| 90 | jModuleName = savedJNIEnv->NewString(JS_GetStringChars(moduleName), |
| 91 | JS_GetStringLength(moduleName)); |
| 92 | if (!jModuleName || savedJNIEnv->ExceptionCheck()) { |
| 93 | tracer.setFail("can't get module name in Java string"); |
| 94 | return JS_FALSE; |
| 95 | } |
gwt.team.jat | d43ad6c | 2007-03-19 22:24:12 +0000 | [diff] [blame] | 96 | tracer.log("module name=%s", JS_GetStringBytes(moduleName)); |
| 97 | } else { |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 98 | tracer.log("null module name"); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 99 | } |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 100 | |
scottb@google.com | bd9fe8c | 2008-08-28 22:56:54 +0000 | [diff] [blame] | 101 | jstring jVersion(0); |
| 102 | if (version) { |
| 103 | jVersion = savedJNIEnv->NewString(JS_GetStringChars(version), |
| 104 | JS_GetStringLength(version)); |
| 105 | if (!jVersion || savedJNIEnv->ExceptionCheck()) { |
| 106 | tracer.setFail("can't get module name in Java string"); |
| 107 | return JS_FALSE; |
| 108 | } |
| 109 | tracer.log("version=%s", JS_GetStringBytes(version)); |
| 110 | } else { |
| 111 | tracer.log("null version"); |
| 112 | } |
| 113 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 114 | jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj)); |
| 115 | jclass objClass = savedJNIEnv->GetObjectClass(externalObject); |
| 116 | if (!objClass || savedJNIEnv->ExceptionCheck()) { |
| 117 | tracer.setFail("can't get LowLevelMoz.ExternalObject class"); |
| 118 | return JS_FALSE; |
| 119 | } |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 120 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 121 | jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "gwtOnLoad", |
scottb@google.com | bd9fe8c | 2008-08-28 22:56:54 +0000 | [diff] [blame] | 122 | "(ILjava/lang/String;Ljava/lang/String;)Z"); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 123 | if (!methodID || savedJNIEnv->ExceptionCheck()) { |
| 124 | tracer.setFail("can't get gwtOnLoad method"); |
| 125 | return JS_FALSE; |
| 126 | } |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 127 | |
gwt.team.jat | d43ad6c | 2007-03-19 22:24:12 +0000 | [diff] [blame] | 128 | tracer.log("scriptGlobal=%08x", unsigned(scriptGlobal.get())); |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 129 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 130 | jboolean result = savedJNIEnv->CallBooleanMethod(externalObject, methodID, |
scottb@google.com | bd9fe8c | 2008-08-28 22:56:54 +0000 | [diff] [blame] | 131 | NS_REINTERPRET_CAST(jint, scriptGlobal.get()), jModuleName, jVersion); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 132 | if (savedJNIEnv->ExceptionCheck()) { |
| 133 | tracer.setFail("LowLevelMoz.ExternalObject.gwtOnLoad() threw an exception"); |
| 134 | return JS_FALSE; |
| 135 | } |
| 136 | *rval = BOOLEAN_TO_JSVAL((result == JNI_FALSE) ? JS_FALSE : JS_TRUE); |
| 137 | return JS_TRUE; |
| 138 | } |
| 139 | |
jat@google.com | e7f61a7 | 2008-12-24 00:45:21 +0000 | [diff] [blame] | 140 | /* |
| 141 | * definition of JavaScript initModule method which maps to the Java |
| 142 | * initModule method. |
| 143 | */ |
| 144 | static JSBool initModule(JSContext *cx, JSObject *obj, uintN argc, |
| 145 | jsval *argv, jsval *rval) |
| 146 | { |
| 147 | Tracer tracer("initModule"); |
| 148 | tracer.log("context=%08x", unsigned(cx)); |
| 149 | JsRootedValue::ContextManager context(cx); |
| 150 | JsRootedValue::ensureRuntime(cx); |
| 151 | if (argc < 1) { |
| 152 | tracer.setFail("less than 1 args"); |
| 153 | return JS_FALSE; |
| 154 | } |
| 155 | |
| 156 | JSString* moduleName = 0; |
| 157 | if (argv[0] != JSVAL_NULL && argv[0] != JSVAL_VOID) { |
| 158 | moduleName = JS_ValueToString(cx, argv[0]); |
| 159 | } |
| 160 | |
| 161 | jstring jModuleName(0); |
| 162 | if (moduleName) { |
| 163 | jModuleName = savedJNIEnv->NewString(JS_GetStringChars(moduleName), |
| 164 | JS_GetStringLength(moduleName)); |
| 165 | if (!jModuleName || savedJNIEnv->ExceptionCheck()) { |
| 166 | tracer.setFail("can't get module name in Java string"); |
| 167 | return JS_FALSE; |
| 168 | } |
| 169 | tracer.log("module name=%s", JS_GetStringBytes(moduleName)); |
| 170 | } else { |
| 171 | tracer.log("null module name"); |
| 172 | } |
| 173 | |
| 174 | jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj)); |
| 175 | jclass objClass = savedJNIEnv->GetObjectClass(externalObject); |
| 176 | if (!objClass || savedJNIEnv->ExceptionCheck()) { |
| 177 | tracer.setFail("can't get LowLevelMoz.ExternalObject class"); |
| 178 | return JS_FALSE; |
| 179 | } |
| 180 | |
| 181 | jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "initModule", |
| 182 | "(Ljava/lang/String;)Z"); |
| 183 | if (!methodID || savedJNIEnv->ExceptionCheck()) { |
| 184 | tracer.setFail("can't get initModule method"); |
| 185 | return JS_FALSE; |
| 186 | } |
| 187 | |
| 188 | jboolean result = savedJNIEnv->CallBooleanMethod(externalObject, methodID, |
| 189 | jModuleName); |
| 190 | if (savedJNIEnv->ExceptionCheck()) { |
| 191 | tracer.setFail("LowLevelMoz.ExternalObject.initModule() threw an exception"); |
| 192 | return JS_FALSE; |
| 193 | } |
| 194 | *rval = BOOLEAN_TO_JSVAL((result == JNI_FALSE) ? JS_FALSE : JS_TRUE); |
| 195 | return JS_TRUE; |
| 196 | } |
| 197 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 198 | /*=======================================================================*/ |
| 199 | /* Implementation of the getProperty, setProperty, and finalize methods */ |
| 200 | /* for the JavaScript class gwt_external_class. */ |
| 201 | /*=======================================================================*/ |
| 202 | |
| 203 | static JSBool JS_DLL_CALLBACK gwt_external_getProperty(JSContext *cx, |
| 204 | JSObject *obj, jsval id, jsval *vp) |
| 205 | { |
| 206 | Tracer tracer("gwt_external_getProperty"); |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 207 | JsRootedValue::ContextManager context(cx); |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 208 | if (*vp != JSVAL_VOID) { |
| 209 | // we setup the gwtOnLoad function as a property in GetScriptObject and |
| 210 | // do not maintain a copy of it anywhere. So, if there is a cached |
| 211 | // value for a property we must return it. As we never redefine any |
| 212 | // property values, this is safe. If we were going to keep this code |
| 213 | // around and add Toby's profiling code we would need to revisit this. |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 214 | return JS_TRUE; |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 215 | } |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 216 | |
| 217 | if (!JSVAL_IS_STRING(id)) { |
| 218 | tracer.setFail("not a string"); |
| 219 | return JS_FALSE; |
| 220 | } |
| 221 | JsStringWrap jsStr(cx, id); |
| 222 | tracer.log("obj=%08x, property=%.*s", obj, jsStr.length(), jsStr.bytes()); |
| 223 | |
| 224 | // All this is for calling resolveReference which only returns void. So, |
| 225 | // just replace this code to return void for now. TODO(jat): revisit when |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 226 | // merging in Toby's code. |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 227 | #if 0 |
| 228 | jstring jident = savedJNIEnv->NewString(jsStr.chars(), jsStr.length()); |
| 229 | if (!jident || savedJNIEnv->ExceptionCheck()) { |
| 230 | tracer.setFail("can't create Java string "); |
| 231 | return JS_FALSE; |
| 232 | } |
| 233 | jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj)); |
| 234 | jclass objClass = savedJNIEnv->GetObjectClass(externalObject); |
| 235 | if (!objClass || savedJNIEnv->ExceptionCheck()) { |
| 236 | tracer.setFail("can't find Java class for JS object"); |
| 237 | return JS_FALSE; |
| 238 | } |
| 239 | |
| 240 | jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "resolveReference", |
| 241 | "(Ljava/lang/String;)I"); |
| 242 | if (!methodID || savedJNIEnv->ExceptionCheck()) { |
| 243 | tracer.setFail("exception getting method for int resolveReference(String)"); |
| 244 | return JS_FALSE; |
| 245 | } |
| 246 | int retval = savedJNIEnv->CallIntMethod(externalObject, methodID, jident); |
| 247 | if (savedJNIEnv->ExceptionCheck()) { |
| 248 | tracer.setFail("exception calling int resolveReference(String)"); |
| 249 | return JS_FALSE; |
| 250 | } |
| 251 | *vp = retval; |
| 252 | #else |
| 253 | *vp = JSVAL_VOID; |
| 254 | #endif |
| 255 | return JS_TRUE; |
| 256 | } |
| 257 | |
| 258 | static void JS_DLL_CALLBACK gwt_external_finalize(JSContext *cx, JSObject *obj) |
| 259 | { |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 260 | // We don't need to push a context if all we do is DeleteGlobalRef |
| 261 | Tracer tracer("gwt_external_finalize", obj); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 262 | jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj)); |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 263 | if (externalObject) { |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 264 | savedJNIEnv->DeleteGlobalRef(externalObject); |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 265 | } |
| 266 | JS_FinalizeStub(cx, obj); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 267 | } |
| 268 | |
| 269 | static JSBool JS_DLL_CALLBACK gwt_external_setProperty(JSContext *cx, |
| 270 | JSObject *obj, jsval id, jsval *vp) |
| 271 | { |
| 272 | return JS_FALSE; |
| 273 | } |
| 274 | |
| 275 | static JSClass gwt_external_class = { |
| 276 | "gwt_external_class", JSCLASS_HAS_PRIVATE, |
| 277 | JS_PropertyStub, JS_PropertyStub, gwt_external_getProperty, |
| 278 | gwt_external_setProperty, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, |
| 279 | gwt_external_finalize, |
| 280 | JSCLASS_NO_OPTIONAL_MEMBERS |
| 281 | }; |
| 282 | |
| 283 | NS_IMPL_ISUPPORTS1(ExternalWrapper, nsIScriptObjectOwner) |
| 284 | |
| 285 | /* |
| 286 | * Create a new LowLevelMoz.ExternalObject instance and a JavaScript object |
| 287 | * that refers to it, mapping the gwtOnLoad member function mapping to |
| 288 | * a Javascript method. |
| 289 | */ |
| 290 | NS_IMETHODIMP ExternalWrapper::GetScriptObject(nsIScriptContext *aContext, |
| 291 | void** aScriptObject) |
| 292 | { |
| 293 | Tracer tracer("ExternalWrapper::GetScriptObject"); |
| 294 | if (!aScriptObject) { |
| 295 | tracer.setFail("null script object pointer"); |
| 296 | return NS_ERROR_INVALID_POINTER; |
| 297 | } |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 298 | if (!jsWindowExternalObject) { |
| 299 | JSContext* cx = NS_REINTERPRET_CAST(JSContext*, |
| 300 | aContext->GetNativeContext()); |
| 301 | if (!cx) { |
| 302 | tracer.setFail("can't get JSContext"); |
| 303 | return NS_ERROR_UNEXPECTED; |
| 304 | } |
| 305 | JsRootedValue::ContextManager context(cx); |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 306 | *aScriptObject = 0; |
| 307 | |
| 308 | nsIScriptGlobalObject* globalObject = aContext->GetGlobalObject(); |
| 309 | nsCOMPtr<nsIDOMWindow> domWindow(do_QueryInterface(globalObject)); |
| 310 | if (!domWindow) { |
| 311 | tracer.setFail("can't get DOM window"); |
| 312 | return NS_ERROR_UNEXPECTED; |
| 313 | } |
| 314 | nsCOMPtr<nsIDOMWindow> topWindow; |
| 315 | domWindow->GetTop(getter_AddRefs(topWindow)); |
| 316 | if (!topWindow) { |
| 317 | tracer.setFail("Can't get top window"); |
| 318 | return NS_ERROR_UNEXPECTED; |
| 319 | } |
| 320 | |
| 321 | tracer.log("savedJNIEnv=%08x, llClass=%08x", unsigned(savedJNIEnv), |
| 322 | lowLevelMozClass); |
| 323 | |
| 324 | jmethodID methodID = savedJNIEnv->GetStaticMethodID(lowLevelMozClass, |
| 325 | "createExternalObjectForDOMWindow", |
| 326 | "(I)Lcom/google/gwt/dev/shell/moz/LowLevelMoz$ExternalObject;"); |
| 327 | if (!methodID || savedJNIEnv->ExceptionCheck()) { |
| 328 | tracer.setFail("Can't get createExternalObjectForDOMWindow method"); |
| 329 | return NS_ERROR_UNEXPECTED; |
| 330 | } |
| 331 | |
| 332 | jobject externalObject = savedJNIEnv->CallStaticObjectMethod( |
| 333 | lowLevelMozClass, methodID, NS_REINTERPRET_CAST(jint, topWindow.get())); |
| 334 | if (!externalObject || savedJNIEnv->ExceptionCheck()) { |
| 335 | tracer.setFail("createExternalObjectForDOMWindow failed"); |
| 336 | return NS_ERROR_UNEXPECTED; |
| 337 | } |
| 338 | externalObject = savedJNIEnv->NewGlobalRef(externalObject); |
| 339 | if (!externalObject || savedJNIEnv->ExceptionCheck()) { |
| 340 | tracer.setFail("can't get GlobalRef for external object"); |
| 341 | return NS_ERROR_UNEXPECTED; |
| 342 | } |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 343 | JSObject* newObj = JS_NewObject(cx, &gwt_external_class, 0, |
| 344 | globalObject->GetGlobalJSObject()); |
| 345 | if (!newObj) { |
| 346 | tracer.setFail("can't create new gwt_external_class object"); |
| 347 | return NS_ERROR_OUT_OF_MEMORY; |
| 348 | } |
| 349 | if (!JS_SetPrivate(cx, newObj, externalObject)) { |
| 350 | savedJNIEnv->DeleteGlobalRef(externalObject); |
| 351 | tracer.setFail("can't store external object private reference"); |
| 352 | return NS_ERROR_UNEXPECTED; |
| 353 | } |
| 354 | |
| 355 | if (!JS_DefineFunction(cx, newObj, "gwtOnLoad", gwtOnLoad, 3, |
| 356 | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { |
| 357 | tracer.setFail("can't define gwtOnLoad function on JavaScript object"); |
| 358 | return NS_ERROR_UNEXPECTED; |
| 359 | } |
jat@google.com | e7f61a7 | 2008-12-24 00:45:21 +0000 | [diff] [blame] | 360 | if (!JS_DefineFunction(cx, newObj, "initModule", initModule, 1, |
| 361 | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { |
| 362 | tracer.setFail("can't define initModule function on JavaScript object"); |
| 363 | return NS_ERROR_UNEXPECTED; |
| 364 | } |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 365 | jsWindowExternalObject = newObj; |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 366 | } |
| 367 | |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 368 | *aScriptObject = jsWindowExternalObject; |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 369 | return NS_OK; |
| 370 | } |
| 371 | |
| 372 | NS_IMETHODIMP ExternalWrapper::SetScriptObject(void* aScriptObject) |
| 373 | { |
gwt.team.scottb | 63d38d0 | 2007-07-25 20:51:13 +0000 | [diff] [blame] | 374 | jsWindowExternalObject = aScriptObject; |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 375 | return NS_OK; |
| 376 | } |
| 377 | |
| 378 | NS_IMPL_ISUPPORTS1(nsRpExternalFactory, nsIFactory) |
| 379 | |
| 380 | NS_IMETHODIMP nsRpExternalFactory::CreateInstance(nsISupports *aOuter, |
| 381 | const nsIID& aIID, void** aResult) |
| 382 | { |
| 383 | Tracer tracer("nsRpExternalFactory::CreateInstance"); |
| 384 | if (!aResult) { |
| 385 | tracer.setFail("null pointer for return value"); |
| 386 | return NS_ERROR_INVALID_POINTER; |
| 387 | } |
| 388 | *aResult = NULL; |
| 389 | |
| 390 | if (aOuter) { |
| 391 | tracer.setFail("aOuter is not null"); |
| 392 | return NS_ERROR_NO_AGGREGATION; |
| 393 | } |
| 394 | |
| 395 | nsISupports* object = new ExternalWrapper(); |
| 396 | if (!object) { |
| 397 | tracer.setFail("can't create a new ExternalWrapper"); |
| 398 | return NS_ERROR_OUT_OF_MEMORY; |
| 399 | } |
scottb@google.com | 6435ea2 | 2008-06-11 01:12:18 +0000 | [diff] [blame] | 400 | |
gwt.team.jat | c85cb7f | 2007-03-02 20:13:50 +0000 | [diff] [blame] | 401 | nsresult result = object->QueryInterface(aIID, aResult); |
| 402 | if (!*aResult || NS_FAILED(result)) { |
| 403 | tracer.setFail("ExternalWrapper::QueryInterface failed"); |
| 404 | delete object; |
| 405 | } |
| 406 | return result; |
| 407 | } |
| 408 | |
| 409 | NS_IMETHODIMP nsRpExternalFactory::LockFactory(PRBool lock) |
| 410 | { |
| 411 | return NS_ERROR_NOT_IMPLEMENTED; |
| 412 | } |