# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. # License: New BSD License. # Website: http://code.google.com/p/cefpython/ include "cefpython.pyx" cdef dict g_pyFrames = {} cdef object GetUniqueFrameId(int browserId, object frameId): return str(browserId) +"#"+ str(frameId) cdef PyFrame GetPyFrameById(int browserId, object frameId): cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) if uniqueFrameId in g_pyFrames: return g_pyFrames[uniqueFrameId] return None cdef PyFrame GetPyFrame(CefRefPtr[CefFrame] cefFrame): global g_pyFrames if cefFrame == NULL or not cefFrame.get(): Debug("GetPyFrame(): returning None") return cdef PyFrame pyFrame # long long cdef object frameId = cefFrame.get().GetIdentifier() cdef int browserId = cefFrame.get().GetBrowser().get().GetIdentifier() assert (frameId and browserId), "frameId or browserId empty" cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) if uniqueFrameId in g_pyFrames: return g_pyFrames[uniqueFrameId] for uFid, pyFrame in g_pyFrames.items(): if not pyFrame.cefFrame.get(): Debug("GetPyFrame(): removing an empty CefFrame reference, " \ "uniqueFrameId = %s" % uniqueFrameId) del g_pyFrames[uFid] # Debug("GetPyFrame(): creating new PyFrame, frameId=%s" % frameId) pyFrame = PyFrame(browserId, frameId) pyFrame.cefFrame = cefFrame g_pyFrames[uniqueFrameId] = pyFrame return pyFrame cdef void RemovePyFrame(int browserId, object frameId) except *: # Called from V8ContextHandler_OnContextReleased(). global g_pyFrames cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) if uniqueFrameId in g_pyFrames: Debug("del g_pyFrames[%s]" % uniqueFrameId) del g_pyFrames[uniqueFrameId] else: Debug("RemovePyFrame() FAILED: uniqueFrameId = %s" % uniqueFrameId) cdef void RemovePyFramesForBrowser(int browserId) except *: # Called from LifespanHandler_BeforeClose(). cdef list toRemove = [] cdef object uniqueFrameId cdef PyFrame pyFrame global g_pyFrames for uniqueFrameId, pyFrame in g_pyFrames.iteritems(): if pyFrame.GetBrowserIdentifier() == browserId: toRemove.append(uniqueFrameId) for uniqueFrameId in toRemove: Debug("del g_pyFrames[%s]" % uniqueFrameId) del g_pyFrames[uniqueFrameId] cdef class PyFrame: cdef CefRefPtr[CefFrame] cefFrame cdef int browserId cdef object frameId cdef CefRefPtr[CefFrame] GetCefFrame(self) except *: # Do not call IsValid() here, if the frame does not exist # then no big deal, no reason to crash the application. # The CEF calls will fail, but they also won't cause crash. if self.cefFrame != NULL and self.cefFrame.get(): return self.cefFrame raise Exception("PyFrame.GetCefFrame() failed: CefFrame was destroyed") def __init__(self, int browserId, int frameId): self.browserId = browserId self.frameId = frameId cpdef py_bool IsValid(self): if self.cefFrame != NULL and self.cefFrame.get() \ and self.cefFrame.get().IsValid(): return True return False def CallFunction(self, *args): # DEPRECATED - keep for backwards compatibility. self.ExecuteFunction(*args) cpdef py_void Copy(self): self.GetCefFrame().get().Copy() cpdef py_void Cut(self): self.GetCefFrame().get().Cut() cpdef py_void Delete(self): self.GetCefFrame().get().Delete() def ExecuteFunction(self, funcName, *args): # No need to enter V8 context as we're calling javascript # asynchronously using ExecuteJavascript() function. code = funcName+"(" for i in range(0, len(args)): if i != 0: code += ", " code += json.dumps(args[i]) code += ")" self.ExecuteJavascript(code) cpdef py_void ExecuteJavascript(self, py_string jsCode, py_string scriptUrl="", int startLine=0): self.GetCefFrame().get().ExecuteJavaScript(PyToCefStringValue(jsCode), PyToCefStringValue(scriptUrl), startLine) cpdef object GetIdentifier(self): # It is better to save browser and frame identifiers during # browser instantiation. When freeing PyBrowser and PyFrame # we need these identifiers. CefFrame and CefBrowser may already # be freed and calling methods on these objects may fail, this # may or may not include GetIdentifier() method, but let's be sure. return self.frameId cpdef PyFrame GetParent(self): return GetPyFrame(self.GetCefFrame().get().GetParent()) cpdef PyBrowser GetBrowser(self): return GetPyBrowser(self.GetCefFrame().get().GetBrowser()) cpdef int GetBrowserIdentifier(self) except *: return self.browserId cpdef str GetName(self): return CefToPyString(self.GetCefFrame().get().GetName()) cpdef py_void GetSource(self, object visitor): self.GetCefFrame().get().GetSource(CreateStringVisitor(visitor)) cpdef py_void GetText(self, object visitor): self.GetCefFrame().get().GetText(CreateStringVisitor(visitor)) cpdef str GetUrl(self): return CefToPyString(self.GetCefFrame().get().GetURL()) cpdef py_bool IsFocused(self): return self.GetCefFrame().get().IsFocused() cpdef py_bool IsMain(self): return self.GetCefFrame().get().IsMain() cpdef py_void LoadString(self, py_string value, py_string url): cdef CefString cefValue cdef CefString cefUrl PyToCefString(value, cefValue) PyToCefString(url, cefUrl) self.GetCefFrame().get().LoadString(cefValue, cefUrl) cpdef py_void LoadUrl(self, py_string url): url = GetNavigateUrl(url) cdef CefString cefUrl PyToCefString(url, cefUrl) self.GetCefFrame().get().LoadURL(cefUrl) cpdef py_void Paste(self): self.GetCefFrame().get().Paste() cpdef py_void Redo(self): self.GetCefFrame().get().Redo() cpdef py_void SelectAll(self): self.GetCefFrame().get().SelectAll() cpdef py_void Undo(self): self.GetCefFrame().get().Undo() cpdef py_void ViewSource(self): self.GetCefFrame().get().ViewSource()