55
66#include " Stdafx.h"
77
8- #include " include\base\cef_logging.h"
98#include " CefBrowserWrapper.h"
109#include " CefAppUnmanagedWrapper.h"
1110#include " RegisterBoundObjectHandler.h"
1211#include " JavascriptRootObjectWrapper.h"
1312#include " Serialization\V8Serialization.h"
1413#include " Serialization\JsObjectsSerialization.h"
15- #include " Async/ JavascriptAsyncMethodCallback.h"
14+ #include " Async\ JavascriptAsyncMethodCallback.h"
1615#include " ..\CefSharp.Core\Internals\Messaging\Messages.h"
1716#include " ..\CefSharp.Core\Internals\Serialization\Primitives.h"
1817
18+ using namespace System ;
1919using namespace System ::Diagnostics;
2020using namespace System ::Collections::Generic;
2121using namespace CefSharp ::Internals::Messaging;
@@ -75,21 +75,13 @@ namespace CefSharp
7575
7676 if (_legacyBindingEnabled)
7777 {
78- auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier (), true );
79-
80- auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
81- auto frameId = frame->GetIdentifier ();
82-
8378 if (_javascriptObjects->Count > 0 )
8479 {
85- JavascriptRootObjectWrapper^ rootObject;
86- if (!rootObjectWrappers-> TryGetValue (frameId, rootObject) )
80+ auto rootObject = GetJsRootObjectWrapper (browser-> GetIdentifier (), frame-> GetIdentifier ()) ;
81+ if (rootObject != nullptr )
8782 {
88- rootObject = gcnew JavascriptRootObjectWrapper (browser->GetIdentifier (), browserWrapper->BrowserProcess );
89- rootObjectWrappers->TryAdd (frameId, rootObject);
83+ rootObject->Bind (_javascriptObjects->Values , context->GetGlobal ());
9084 }
91-
92- rootObject->Bind (_javascriptObjects->Values , context->GetGlobal ());
9385 }
9486 }
9587
@@ -98,15 +90,21 @@ namespace CefSharp
9890 auto cefSharpObj = CefV8Value::CreateObject (NULL , NULL );
9991 global->SetValue (" CefSharp" , cefSharpObj, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
10092
101- auto bindObjAsyncFunction = CefV8Value::CreateFunction (" BindObjectAsync" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects));
93+ auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier ());
94+
95+ // TODO: JSB: Split functions into their own classes
96+ // Browser wrapper is only used for BindObjectAsync
97+ auto bindObjAsyncFunction = CefV8Value::CreateFunction (" BindObjectAsync" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects, browserWrapper));
10298 cefSharpObj->SetValue (" BindObjectAsync" , bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
10399
104- auto unBindObFunction = CefV8Value::CreateFunction (" DeleteBoundObject" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects));
100+ auto unBindObFunction = CefV8Value::CreateFunction (" DeleteBoundObject" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects, nullptr ));
105101 cefSharpObj->SetValue (" DeleteBoundObject" , unBindObFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
106102
107- // TODO: JSB We could in theory auto bind all the cached objects which would resemble the original JSB behaviour, if
108- // the cache is empty which would be the case for any cross-site navigation request or the first request made to a browser instance
109- // then no objects would be bound by default
103+ auto removeObjectFromCacheFunction = CefV8Value::CreateFunction (" RemoveObjectFromCache" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects, nullptr ));
104+ cefSharpObj->SetValue (" RemoveObjectFromCache" , removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
105+
106+ auto isObjectCachedFunction = CefV8Value::CreateFunction (" IsObjectCached" , new RegisterBoundObjectHandler (_registerBoundObjectRegistry, _javascriptObjects, nullptr ));
107+ cefSharpObj->SetValue (" IsObjectCached" , isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
110108 };
111109
112110 void CefAppUnmanagedWrapper::OnContextReleased (CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
@@ -123,7 +121,13 @@ namespace CefSharp
123121 browser->SendProcessMessage (CefProcessId::PID_BROWSER, contextReleasedMessage);
124122 }
125123
126- auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier (), true );
124+ auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier ());
125+
126+ // If we no longer have a browser wrapper reference then there's nothing we can do
127+ if (browserWrapper == nullptr )
128+ {
129+ return ;
130+ }
127131
128132 auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
129133
@@ -177,15 +181,37 @@ namespace CefSharp
177181 browser->SendProcessMessage (CefProcessId::PID_BROWSER, focusedNodeChangedMessage);
178182 }
179183
180- CefBrowserWrapper^ CefAppUnmanagedWrapper::FindBrowserWrapper(int browserId, bool mustExist)
184+ JavascriptRootObjectWrapper^ CefAppUnmanagedWrapper::GetJsRootObjectWrapper(int browserId, int64 frameId)
185+ {
186+ auto browserWrapper = FindBrowserWrapper (browserId);
187+
188+ if (browserWrapper == nullptr )
189+ {
190+ return nullptr ;
191+ }
192+
193+ auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
194+
195+ JavascriptRootObjectWrapper^ rootObject;
196+ if (!rootObjectWrappers->TryGetValue (frameId, rootObject))
197+ {
198+ rootObject = gcnew JavascriptRootObjectWrapper (browserId, browserWrapper->BrowserProcess );
199+ rootObjectWrappers->TryAdd (frameId, rootObject);
200+ }
201+
202+ return rootObject;
203+ }
204+
205+ CefBrowserWrapper^ CefAppUnmanagedWrapper::FindBrowserWrapper(int browserId)
181206 {
182207 CefBrowserWrapper^ wrapper = nullptr ;
183208
184209 _browserWrappers->TryGetValue (browserId, wrapper);
185210
186- if (mustExist && wrapper == nullptr )
211+ if (wrapper == nullptr )
187212 {
188- throw gcnew InvalidOperationException (String::Format (" Failed to identify BrowserWrapper in OnContextCreated. : {0}" , browserId));
213+ // TODO: Find the syntax for delcaring the native string directly
214+ LOG (ERROR) << StringUtils::ToNative (" Failed to identify BrowserWrapper in OnContextCreated BrowserId:" + browserId).ToString ();
189215 }
190216
191217 return wrapper;
@@ -197,7 +223,7 @@ namespace CefSharp
197223 auto name = message->GetName ();
198224 auto argList = message->GetArgumentList ();
199225
200- auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier (), false );
226+ auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier ());
201227 // Error handling for missing/closed browser
202228 if (browserWrapper == nullptr )
203229 {
@@ -434,28 +460,25 @@ namespace CefSharp
434460 auto callbackId = GetInt64 (argList, 3 );
435461 auto javascriptObjects = DeserializeJsObjects (argList, 4 );
436462
437- // TODO: JSB Implement Caching of JavascriptObjects
438- // Should caching be configurable? On a per object basis?
439- /* for each (JavascriptObject^ obj in Enumerable::OfType<JavascriptObject^>(javascriptObjects))
463+ // Caching of JavascriptObjects
464+ // TODO: JSB Should caching be configurable? On a per object basis?
465+ for each (JavascriptObject^ obj in Enumerable::OfType<JavascriptObject^>(javascriptObjects))
440466 {
441467 if (_javascriptObjects->ContainsKey (obj->JavascriptName ))
442468 {
443469 _javascriptObjects->Remove (obj->JavascriptName );
444470 }
445471 _javascriptObjects->Add (obj->JavascriptName , obj);
446- }*/
447-
448- auto browserWrapper = FindBrowserWrapper (browser->GetIdentifier (), true );
472+ }
449473
450- auto rootObjectWrappers = browserWrapper->JavascriptRootObjectWrappers ;
451474 auto frame = browser->GetFrame (frameId);
452475 if (frame.get ())
453476 {
454- JavascriptRootObjectWrapper^ rootObject;
455- if (!rootObjectWrappers->TryGetValue (frameId, rootObject))
477+ auto rootObject = GetJsRootObjectWrapper (browser->GetIdentifier (), frameId);
478+
479+ if (rootObject == nullptr )
456480 {
457- rootObject = gcnew JavascriptRootObjectWrapper (browser->GetIdentifier (), browserWrapper->BrowserProcess );
458- rootObjectWrappers->TryAdd (frameId, rootObject);
481+ return false ;
459482 }
460483
461484 auto context = frame->GetV8Context ();
@@ -472,6 +495,8 @@ namespace CefSharp
472495 // Response object has no Accessor or Interceptor
473496 auto response = CefV8Value::CreateObject (NULL , NULL );
474497
498+ response->SetValue (" Count" , CefV8Value::CreateInt (javascriptObjects->Count ), CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
499+
475500 if (javascriptObjects->Count > 0 )
476501 {
477502 // TODO: JSB Should we include a list of successfully bound object names?
@@ -486,8 +511,6 @@ namespace CefSharp
486511 callback->Success (response);
487512 }
488513
489- // TODO: JSB deal with failure - no object matching bound
490-
491514 // Send message notifying Browser Process of which objects were bound
492515 // We do this after the objects have been created in the V8Context to gurantee
493516 // they are accessible.
0 commit comments