@@ -144,7 +144,8 @@ void CefPythonApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
144144 if (frame->IsMain ()) {
145145 DoJavascriptBindingsForFrame (browser, frame, context);
146146 } else {
147- if (jsBindings->GetType (" bindToFrames" ) == VTYPE_BOOL
147+ if (jsBindings->HasKey (" bindToFrames" )
148+ && jsBindings->GetType (" bindToFrames" ) == VTYPE_BOOL
148149 && jsBindings->GetBool (" bindToFrames" )) {
149150 DoJavascriptBindingsForFrame (browser, frame, context);
150151 }
@@ -231,6 +232,52 @@ void CefPythonApp::RemoveJavascriptBindings(CefRefPtr<CefBrowser> browser) {
231232 }
232233}
233234
235+ bool CefPythonApp::BindedFunctionExists (CefRefPtr<CefBrowser> browser,
236+ const CefString& funcName) {
237+ CefRefPtr<CefDictionaryValue> jsBindings = GetJavascriptBindings (browser);
238+ if (!jsBindings.get ()) {
239+ return false ;
240+ }
241+ std::string strFuncName = funcName.ToString ();
242+ size_t dotPosition = strFuncName.find (" ." );
243+ if (std::string::npos != dotPosition) {
244+ // This is a method call, funcName == "object.method".
245+ CefString objectName (strFuncName.substr (0 , dotPosition));
246+ CefString methodName (strFuncName.substr (dotPosition, std::string::npos));
247+ if (!(jsBindings->HasKey (" objects" )
248+ && jsBindings->GetType (" objects" ) == VTYPE_DICTIONARY)) {
249+ DebugLog (" Renderer: BindedFunctionExists() FAILED: " \
250+ " objects dictionary not found" );
251+ return false ;
252+ }
253+ CefRefPtr<CefDictionaryValue> objects = \
254+ jsBindings->GetDictionary (" objects" );
255+ if (objects->HasKey (objectName)) {
256+ if (!(objects->GetType (objectName) == VTYPE_DICTIONARY)) {
257+ DebugLog (" Renderer: BindedFunctionExists() FAILED: " \
258+ " objects dictionary has invalid type" );
259+ return false ;
260+ }
261+ CefRefPtr<CefDictionaryValue> methods = \
262+ objects->GetDictionary (objectName);
263+ return methods->HasKey (methodName);
264+ } else {
265+ return false ;
266+ }
267+ } else {
268+ // This is a function call.
269+ if (!(jsBindings->HasKey (" functions" )
270+ && jsBindings->GetType (" functions" ) == VTYPE_DICTIONARY)) {
271+ DebugLog (" Renderer: BindedFunctionExists() FAILED: " \
272+ " functions dictionary not found" );
273+ return false ;
274+ }
275+ CefRefPtr<CefDictionaryValue> functions = \
276+ jsBindings->GetDictionary (" functions" );
277+ return functions->HasKey (funcName);
278+ }
279+ }
280+
234281void CefPythonApp::DoJavascriptBindingsForBrowser (
235282 CefRefPtr<CefBrowser> browser) {
236283 // get frame
@@ -246,7 +293,8 @@ void CefPythonApp::DoJavascriptBindingsForBrowser(
246293 return ;
247294 }
248295 std::vector<int64> frameIds;
249- if (jsBindings->GetType (" bindToFrames" ) == VTYPE_BOOL
296+ if (jsBindings->HasKey (" bindToFrames" )
297+ && jsBindings->GetType (" bindToFrames" ) == VTYPE_BOOL
250298 && jsBindings->GetBool (" bindToFrames" )) {
251299 browser->GetFrameIdentifiers (frameIds);
252300 } else {
@@ -277,16 +325,28 @@ void CefPythonApp::DoJavascriptBindingsForFrame(CefRefPtr<CefBrowser> browser,
277325 return ;
278326 }
279327 DebugLog (" Renderer: DoJavascriptBindingsForFrame(): bindings are set" );
280- if (!(jsBindings->GetType (" functions" ) == VTYPE_LIST
328+ if (!(jsBindings->HasKey (" functions" )
329+ && jsBindings->GetType (" functions" ) == VTYPE_DICTIONARY
330+ && jsBindings->HasKey (" properties" )
281331 && jsBindings->GetType (" properties" ) == VTYPE_DICTIONARY
332+ && jsBindings->HasKey (" objects" )
282333 && jsBindings->GetType (" objects" ) == VTYPE_DICTIONARY
334+ && jsBindings->HasKey (" bindToFrames" )
283335 && jsBindings->GetType (" bindToFrames" ) == VTYPE_BOOL)) {
284336 DebugLog (" Renderer: DoJavascriptBindingsForFrame() FAILED: " \
285337 " invalid data [1]" );
286338 return ;
287339 }
340+ // A context must be explicitly entered before creating a
341+ // V8 Object, Array, Function or Date asynchronously.
342+ bool enteredContext = false ;
343+ if (!context->IsSame (CefV8Context::GetCurrentContext ())) {
344+ enteredContext = true ;
345+ context->Enter ();
346+ }
288347 // TODO: properties, objects, other frames.
289- CefRefPtr<CefListValue> functions = jsBindings->GetList (" functions" );
348+ CefRefPtr<CefDictionaryValue> functions = \
349+ jsBindings->GetDictionary (" functions" );
290350 CefRefPtr<CefDictionaryValue> properties = \
291351 jsBindings->GetDictionary (" properties" );
292352 CefRefPtr<CefDictionaryValue> objects = \
@@ -297,20 +357,29 @@ void CefPythonApp::DoJavascriptBindingsForFrame(CefRefPtr<CefBrowser> browser,
297357 && objects->IsValid ())) {
298358 DebugLog (" Renderer: DoJavascriptBindingsForFrame() FAILED: " \
299359 " invalid data [2]" );
360+ if (enteredContext)
361+ context->Exit ();
300362 return ;
301363 }
302364 CefRefPtr<CefV8Value> v8Window = context->GetGlobal ();
303365 CefRefPtr<CefV8Value> v8Function;
366+ CefRefPtr<CefV8Handler> v8FunctionHandler (new V8FunctionHandler (this ));
304367 // FUNCTIONS.
305- for (unsigned int i = 0 ; i < functions->GetSize (); i++) {
306- if (functions->GetType (i) != VTYPE_STRING) {
307- DebugLog (" Renderer: DoJavascriptBindingsForFrame() FAILED: " \
308- " invalid data [3]" );
309- return ;
310- }
311- CefString funcName = functions->GetString (i);
312- v8Function = CefV8Value::CreateFunction (funcName, v8FunctionHandler_);
368+ std::vector<CefString> functionsVector;
369+ if (!functions->GetKeys (functionsVector)) {
370+ DebugLog (" Renderer: DoJavascriptBindingsForFrame(): " \
371+ " functions->GetKeys() FAILED" );
372+ if (enteredContext)
373+ context->Exit ();
374+ return ;
375+ }
376+ for (std::vector<CefString>::iterator it = functionsVector.begin (); \
377+ it != functionsVector.end (); ++it) {
378+ CefString funcName = *it;
379+ v8Function = CefV8Value::CreateFunction (funcName, v8FunctionHandler);
313380 v8Window->SetValue (funcName, v8Function,
314381 V8_PROPERTY_ATTRIBUTE_NONE);
315382 }
383+ if (enteredContext)
384+ context->Exit ();
316385}
0 commit comments