# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
# License: New BSD License.
# Website: http://code.google.com/p/cefpython/
cdef cpp_map[int, CefRefPtr[CefV8Value]] g_v8JavascriptCallbacks
cdef cpp_map[int, CefRefPtr[CefV8Context]] g_v8JavascriptCallbackContexts
# Next callbackId.
cdef int g_v8JavascriptCallbackCount = 0
cdef int PutV8JavascriptCallback(
CefRefPtr[CefV8Value] v8Value,
CefRefPtr[CefV8Context] v8Context) except *:
global g_v8JavascriptCallbacks
global g_v8JavascriptCallbackContexts
global g_v8JavascriptCallbackCount
g_v8JavascriptCallbackCount += 1
cdef int callbackId = g_v8JavascriptCallbackCount
g_v8JavascriptCallbacks[callbackId] = v8Value
g_v8JavascriptCallbackContexts[callbackId] = v8Context
return callbackId
cdef CefRefPtr[CefV8Value] GetV8JavascriptCallback(
int callbackId) except *:
global g_v8JavascriptCallbacks
if g_v8JavascriptCallbacks.find(callbackId) == g_v8JavascriptCallbacks.end():
raise Exception("GetV8JavascriptCallback() failed: invalid callbackId: %s"
% callbackId)
return g_v8JavascriptCallbacks[callbackId]
cdef CefRefPtr[CefV8Context] GetV8JavascriptCallbackContext(
int callbackId) except *:
global g_v8JavascriptCallbackContexts
if g_v8JavascriptCallbackContexts.find(callbackId) == g_v8JavascriptCallbackContexts.end():
raise Exception("GetV8JavascriptCallbackContext() failed: invalid callbackId: %s"
% callbackId)
return g_v8JavascriptCallbackContexts[callbackId]
cdef void DelV8JavascriptCallback(
int callbackId) except *:
global g_v8JavascriptCallbacks
global g_v8JavascriptCallbackContexts
g_v8JavascriptCallbacks.erase(callbackId)
g_v8JavascriptCallbackContexts.erase(callbackId)
cdef class JavascriptCallback:
cdef int callbackId
def __init__(self, int callbackId):
assert callbackId, "JavascriptCallback.__init__() failed: callbackId is empty"
self.callbackId = callbackId
def __dealloc__(self):
DelV8JavascriptCallback(self.callbackId)
def Call(self, *args):
cdef CefRefPtr[CefV8Value] v8Value = GetV8JavascriptCallback(self.callbackId)
cdef CefRefPtr[CefV8Context] v8Context = GetV8JavascriptCallbackContext(self.callbackId)
cdef CefV8ValueList v8Arguments
cdef CefRefPtr[CefV8Value] v8Retval
cdef CefRefPtr[CefV8Exception] v8Exception
cdef CefV8Exception* v8ExceptionPtr
cdef int i
# Javascript callback may be kept somewhere and later called from
# a different v8 frame context. Need to enter js v8 context before
# calling PyToV8Value().
cdef cpp_bool sameContext = v8Context.get().IsSame(cef_v8_static.GetCurrentContext())
if not sameContext:
Debug("JavascriptCallback.Call(): inside a different context, calling v8Context.Enter()")
assert v8Context.get().Enter(), "v8Context.Enter() failed"
for i in range(0, len(args)):
v8Arguments.push_back(PyToV8Value(args[i], v8Context))
if not sameContext:
assert v8Context.get().Exit(), "v8Context.Exit() failed"
v8Retval = v8Value.get().ExecuteFunctionWithContext(
v8Context,