@@ -156,7 +156,7 @@ namespace CefSharp
156156
157157// TODO: JSB: Split functions into their own classes
158158// Browser wrapper is only used for BindObjectAsync
159- auto bindObjAsyncFunction =CefV8Value::CreateFunction (kBindObjectAsync ,new BindObjectAsyncHandler (_registerBoundObjectRegistry, _javascriptObjects,browserWrapper ));
159+ auto bindObjAsyncFunction =CefV8Value::CreateFunction (kBindObjectAsync ,new BindObjectAsyncHandler (_registerBoundObjectRegistry, _javascriptObjects,rootObject ));
160160auto unBindObjFunction =CefV8Value::CreateFunction (kDeleteBoundObject ,new RegisterBoundObjectHandler (_javascriptObjects));
161161auto removeObjectFromCacheFunction =CefV8Value::CreateFunction (kRemoveObjectFromCache ,new RegisterBoundObjectHandler (_javascriptObjects));
162162auto isObjectCachedFunction =CefV8Value::CreateFunction (kIsObjectCached ,new RegisterBoundObjectHandler (_javascriptObjects));
@@ -220,16 +220,14 @@ namespace CefSharp
220220
221221 frame->SendProcessMessage (CefProcessId::PID_BROWSER, contextReleasedMessage);
222222
223- auto browserWrapper =FindBrowserWrapper (browser-> GetIdentifier ()) ;
223+ auto rootObjectWrappers =_jsRootObjectWrappersByFrameId ;
224224
225- // If we no longer have abrowser wrapper reference then there's nothing we can do
226- if (browserWrapper == nullptr )
225+ // If we no longer have a_jsRootObjectWrappersByFrameId reference then there's nothing we can do
226+ if (Object::ReferenceEquals (rootObjectWrappers, nullptr ) )
227227 {
228228return ;
229229 }
230230
231- auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
232-
233231 JavascriptRootObjectWrapper^ wrapper;
234232if (rootObjectWrappers->TryRemove (StringUtils::ToClr (frame->GetIdentifier ()), wrapper))
235233 {
@@ -305,23 +303,24 @@ namespace CefSharp
305303
306304 JavascriptRootObjectWrapper^ CefAppUnmanagedWrapper::GetJsRootObjectWrapper(int browserId, CefString& frameId)
307305 {
308- auto browserWrapper =FindBrowserWrapper (browserId) ;
306+ auto rootObjectWrappers =_jsRootObjectWrappersByFrameId ;
309307
310- if (browserWrapper == nullptr )
308+ if (Object::ReferenceEquals (rootObjectWrappers, nullptr ) )
311309 {
312310return nullptr ;
313311 }
314312
315- auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
316313auto frameIdClr =StringUtils::ToClr (frameId);
317314
318315 JavascriptRootObjectWrapper^ rootObject;
319316if (!rootObjectWrappers->TryGetValue (frameIdClr, rootObject))
320317 {
321318#ifdef NETCOREAPP
322- rootObject = gcnewJavascriptRootObjectWrapper (browserId );
319+ rootObject = gcnewJavascriptRootObjectWrapper ();
323320#else
324- rootObject = gcnewJavascriptRootObjectWrapper (browserId, browserWrapper->BrowserProcess );
321+ auto browserWrapper =FindBrowserWrapper (browserId);
322+
323+ rootObject = gcnewJavascriptRootObjectWrapper (browserWrapper ==nullptr ?nullptr : browserWrapper->BrowserProcess );
325324#endif
326325 rootObjectWrappers->TryAdd (frameIdClr, rootObject);
327326 }
@@ -350,49 +349,6 @@ namespace CefSharp
350349auto name = message->GetName ();
351350auto argList = message->GetArgumentList ();
352351
353- auto browserWrapper =FindBrowserWrapper (browser->GetIdentifier ());
354- // Error handling for missing/closed browser
355- if (browserWrapper ==nullptr )
356- {
357- if (name ==kJavascriptCallbackDestroyRequest ||
358- name ==kJavascriptRootObjectResponse ||
359- name ==kJavascriptAsyncMethodCallResponse )
360- {
361- // If we can't find the browser wrapper then we'll just
362- // ignore this as it's likely already been disposed of
363- return true ;
364- }
365-
366- CefString responseName;
367- if (name ==kEvaluateJavascriptRequest )
368- {
369- responseName =kEvaluateJavascriptResponse ;
370- }
371- else if (name ==kJavascriptCallbackRequest )
372- {
373- responseName =kJavascriptCallbackResponse ;
374- }
375- else
376- {
377- // TODO: Should be throw an exception here? It's likely that only a CefSharp developer would see this
378- // when they added a new message and haven't yet implemented the render process functionality.
379- throw gcnewException (" Unsupported message type" );
380- }
381-
382- auto callbackId =GetInt64 (argList,0 );
383- auto response =CefProcessMessage::Create (responseName);
384- auto responseArgList = response->GetArgumentList ();
385- auto errorMessage =String::Format (" Request BrowserId : {0} not found it's likely the browser is already closed" , browser->GetIdentifier ());
386-
387- // success: false
388- responseArgList->SetBool (0 ,false );
389- SetInt64 (responseArgList,1 , callbackId);
390- responseArgList->SetString (2 ,StringUtils::ToNative (errorMessage));
391- frame->SendProcessMessage (sourceProcessId, response);
392-
393- return true ;
394- }
395-
396352// these messages are roughly handled the same way
397353if (name ==kEvaluateJavascriptRequest || name ==kJavascriptCallbackRequest )
398354 {
@@ -415,27 +371,13 @@ namespace CefSharp
415371auto frameId =StringUtils::ToClr (frame->GetIdentifier ());
416372int64_t callbackId =GetInt64 (argList,0 );
417373
374+ // NOTE: In the rare case when when OnContextCreated hasn't been called we need to manually create the rootObjectWrapper
375+ // It appears that OnContextCreated is only called for pages that have javascript on them, which makes sense
376+ // as without javascript there is no need for a context.
377+ JavascriptRootObjectWrapper^ rootObjectWrapper =GetJsRootObjectWrapper (browser->GetIdentifier (), frame->GetIdentifier ());
378+
418379if (name ==kEvaluateJavascriptRequest )
419380 {
420- JavascriptRootObjectWrapper^ rootObjectWrapper;
421- browserWrapper->JavascriptRootObjectWrappers ->TryGetValue (frameId, rootObjectWrapper);
422-
423- // NOTE: In the rare case when when OnContextCreated hasn't been called we need to manually create the rootObjectWrapper
424- // It appears that OnContextCreated is only called for pages that have javascript on them, which makes sense
425- // as without javascript there is no need for a context.
426- if (rootObjectWrapper ==nullptr )
427- {
428- #ifdef NETCOREAPP
429- rootObjectWrapper = gcnewJavascriptRootObjectWrapper (browser->GetIdentifier ());
430- #else
431- rootObjectWrapper = gcnewJavascriptRootObjectWrapper (browser->GetIdentifier (), browserWrapper->BrowserProcess );
432- #endif
433-
434- browserWrapper->JavascriptRootObjectWrappers ->TryAdd (frameId, rootObjectWrapper);
435- }
436-
437- auto callbackRegistry = rootObjectWrapper->CallbackRegistry ;
438-
439381auto script = argList->GetString (1 );
440382auto scriptUrl = argList->GetString (2 );
441383auto startLine = argList->GetInt (3 );
@@ -480,8 +422,17 @@ namespace CefSharp
480422 }
481423else
482424 {
483- auto responseArgList = response->GetArgumentList ();
484- SerializeV8Object (result, responseArgList,2 , callbackRegistry);
425+ auto callbackRegistry = rootObjectWrapper ==nullptr ?nullptr : rootObjectWrapper->CallbackRegistry ;
426+
427+ if (callbackRegistry ==nullptr )
428+ {
429+ errorMessage =StringUtils::ToNative (" The callback registry for Frame" + frameId +" is no longer available." );
430+ }
431+ else
432+ {
433+ auto responseArgList = response->GetArgumentList ();
434+ SerializeV8Object (result, responseArgList,2 , callbackRegistry);
435+ }
485436 }
486437 }
487438else
@@ -506,8 +457,6 @@ namespace CefSharp
506457 }
507458else
508459 {
509- JavascriptRootObjectWrapper^ rootObjectWrapper;
510- browserWrapper->JavascriptRootObjectWrappers ->TryGetValue (frameId, rootObjectWrapper);
511460auto callbackRegistry = rootObjectWrapper ==nullptr ?nullptr : rootObjectWrapper->CallbackRegistry ;
512461if (callbackRegistry ==nullptr )
513462 {
@@ -616,7 +565,7 @@ namespace CefSharp
616565 {
617566auto jsCallbackId =GetInt64 (argList,0 );
618567 JavascriptRootObjectWrapper^ rootObjectWrapper;
619- browserWrapper-> JavascriptRootObjectWrappers ->TryGetValue (StringUtils::ToClr (frame->GetIdentifier ()), rootObjectWrapper);
568+ _jsRootObjectWrappersByFrameId ->TryGetValue (StringUtils::ToClr (frame->GetIdentifier ()), rootObjectWrapper);
620569if (rootObjectWrapper !=nullptr && rootObjectWrapper->CallbackRegistry !=nullptr )
621570 {
622571 rootObjectWrapper->CallbackRegistry ->Deregister (jsCallbackId);
@@ -728,7 +677,7 @@ namespace CefSharp
728677auto callbackId =GetInt64 (argList,0 );
729678
730679 JavascriptRootObjectWrapper^ rootObjectWrapper;
731- browserWrapper-> JavascriptRootObjectWrappers ->TryGetValue (frameId, rootObjectWrapper);
680+ _jsRootObjectWrappersByFrameId ->TryGetValue (frameId, rootObjectWrapper);
732681
733682if (rootObjectWrapper !=nullptr )
734683 {