Skip to content

Commit ea73364

Browse files
committed
Javascript bindings work, but no arguments can be passed yet. Binding to popups and frames is done. Javascript callbacks still todo.
Issue 2 (application error on main window close) was fixed.
1 parent 25f327c commit ea73364

28 files changed

+1213
-118
lines changed

browser.pyx

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,23 @@ __browserInnerWindows = {} # topWindowID : innerWindowID (CefBrowser.GetWindowHa
2323

2424
class PyBrowser:
2525

26-
topWindowID = 0
27-
innerWindowID = 0
28-
handlers = {}
26+
__topWindowID = 0
27+
__innerWindowID = 0
28+
__clientHandlers = {} # Dictionary.
29+
__javascriptBindings = None # JavascriptBindings class.
2930

30-
def __init__(self, topWindowID, innerWindowID, handlers):
31+
def __init__(self, topWindowID, innerWindowID, clientHandlers={}, javascriptBindings=None):
32+
33+
self.__topWindowID = topWindowID
34+
self.__innerWindowID = innerWindowID
35+
36+
clientHandlers = clientHandlers if clientHandlers else {}
37+
javascriptBindings = javascriptBindings if javascriptBindings else None
3138

32-
self.topWindowID = topWindowID
33-
self.innerWindowID = innerWindowID
34-
3539
assert win32gui.IsWindow(innerWindowID), "Invalid window handle (innerWindowID)"
3640

3741
cdef CefRefPtr[CefBrowser] cefBrowser
38-
if -1 != self.topWindowID:
42+
if -1 != self.__topWindowID:
3943

4044
# We do this check only for non-popup windows.
4145

@@ -52,13 +56,29 @@ class PyBrowser:
5256
# is a global object and is automatically inherited by implicitily created popup
5357
# browser windows.
5458

55-
cefBrowser = GetCefBrowserByInnerWindowID(self.innerWindowID)
56-
assert <void*>cefBrowser != NULL, "CefBrowser not found for this innerWindowID: %s" % self.innerWindowID
59+
cefBrowser = GetCefBrowserByInnerWindowID(self.__innerWindowID)
60+
assert <void*>cefBrowser != NULL, "CefBrowser not found for this innerWindowID: %s" % self.__innerWindowID
5761

58-
self.__checkHandlers(handlers)
59-
self.handlers = handlers
62+
self.__checkClientHandlers(clientHandlers)
63+
self.__clientHandlers = clientHandlers
64+
65+
self.__checkJavascriptBindings(javascriptBindings)
66+
self.__javascriptBindings = javascriptBindings
67+
68+
def __checkJavascriptBindings(self, bindings):
6069

61-
def __checkHandlers(self, handlers):
70+
if not bindings:
71+
return
72+
if not isinstance(bindings, JavascriptBindings):
73+
raise Exception("Creating PyBrowser() failed: javascriptBindings is not a JavascriptBindings class.")
74+
75+
def __checkClientHandlers(self, handlers):
76+
77+
# handlers["OnLoadStart"] = StartFunc
78+
# handlers["OnLoadEnd"] = (EndFunc, None, EndFunc)
79+
# tuple[0] - the handler to call for the main frame.
80+
# tuple[1] - the handler to call for the inner frames.
81+
# tuple[2] - the handler to call for the popups.
6282

6383
allowedHandlers = []
6484

@@ -68,32 +88,51 @@ class PyBrowser:
6888
allowedHandlers += ["OnKeyEvent"]
6989

7090
for key in handlers:
91+
handler = handlers[key]
92+
if type(handler) == types.TupleType and len(handler) != 3:
93+
raise Exception("PyBrowser.__init__() failed: invalid client handler, tuple's length must be 3. Key=%s", key)
7194
if key not in allowedHandlers:
7295
raise Exception("Unknown handler: %s, mistyped?" % key)
7396

7497
# Internal.
75-
def GetHandler(self, name):
98+
def IsPopup(self):
99+
100+
# TODO: implement LifeSpanHandler.OnBeforePopup() to detect popups.
101+
return self.__topWindowID == -1
102+
103+
# Internal.
104+
def GetJavascriptBindings(self):
105+
106+
return self.__javascriptBindings
107+
108+
# Internal.
109+
def GetClientHandler(self, name):
110+
111+
if name in self.__clientHandlers:
112+
return self.__clientHandlers[name]
113+
114+
# Internal.
115+
def GetClientHandlers(self):
76116

77-
if name in self.handlers:
78-
return self.handlers[name]
117+
return self.__clientHandlers
79118

80119
# PUBLIC API.
81120

82121
def CanGoBack(self):
83122

84-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
123+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
85124
cdef cbool canGoBack = (<CefBrowser*>(cefBrowser.get())).CanGoBack()
86125
return canGoBack
87126

88127
def CanGoForward(self):
89128

90-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
129+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
91130
cdef cbool canGoForward = (<CefBrowser*>(cefBrowser.get())).CanGoForward()
92131
return canGoForward
93132

94133
def ClearHistory(self):
95134

96-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
135+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
97136
(<CefBrowser*>(cefBrowser.get())).ClearHistory()
98137

99138
def CloseBrowser(self):
@@ -102,30 +141,30 @@ class PyBrowser:
102141
global __pyBrowsers
103142
global __browserInnerWindows
104143

105-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
106-
__cefBrowsers.erase(<int>self.innerWindowID)
107-
del __pyBrowsers[self.innerWindowID]
144+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
145+
__cefBrowsers.erase(<int>self.__innerWindowID)
146+
del __pyBrowsers[self.__innerWindowID]
108147

109148
# -1 == Popup, the window wasn't created by us, so we don't have the topWindowID.
110149
# See -1 value in GetPyBrowserByCefBrowser().
111-
if -1 != self.topWindowID:
112-
del __browserInnerWindows[self.topWindowID]
150+
if -1 != self.__topWindowID:
151+
del __browserInnerWindows[self.__topWindowID]
113152

114-
self.topWindowID = 0
115-
self.innerWindowID = 0
153+
self.__topWindowID = 0
154+
self.__innerWindowID = 0
116155
(<CefBrowser*>(cefBrowser.get())).ParentWindowWillClose()
117156

118157
# This is probably not needed, turning it off, maybe it will fix memory read errors when closing app?
119158
#(<CefBrowser*>(cefBrowser.get())).CloseBrowser()
120159

121160
def CloseDevTools(self):
122161

123-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
162+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
124163
(<CefBrowser*>(cefBrowser.get())).CloseDevTools()
125164

126165
def Find(self, searchID, searchText, forward, matchCase, findNext):
127166

128-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
167+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
129168

130169
cdef CefString cefSearchText
131170
cefSearchText.FromASCII(<char*>searchText)
@@ -136,15 +175,15 @@ class PyBrowser:
136175
def GetFocusedFrame(self):
137176

138177
assert CurrentlyOn(TID_UI), "Browser.GetFocusedFrame() should only be called on the UI thread"
139-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
178+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
140179
cdef CefRefPtr[CefFrame] cefFrame = (<CefBrowser*>(cefBrowser.get())).GetFocusedFrame()
141180

142181
return GetPyFrameByCefFrame(cefFrame)
143182

144183
def GetFrame(self, name):
145184

146185
assert CurrentlyOn(TID_UI), "Browser.GetFrame() should only be called on the UI thread"
147-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
186+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
148187

149188
cdef CefString cefName
150189
cefName.FromASCII(<char*>name)
@@ -155,7 +194,7 @@ class PyBrowser:
155194
def GetFrameNames(self):
156195

157196
assert CurrentlyOn(TID_UI), "Browser.GetFrameNames() should only be called on the UI thread"
158-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
197+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
159198

160199
cdef vector[CefString] cefNames
161200
(<CefBrowser*>(cefBrowser.get())).GetFrameNames(cefNames)
@@ -172,14 +211,14 @@ class PyBrowser:
172211

173212
def GetMainFrame(self):
174213

175-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
214+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
176215
cdef CefRefPtr[CefFrame] cefFrame = (<CefBrowser*>(cefBrowser.get())).GetMainFrame()
177216

178217
return GetPyFrameByCefFrame(cefFrame)
179218

180219
def GetOpenerWindowID(self):
181220

182-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
221+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
183222
cdef HWND hwnd = (<CefBrowser*>(cefBrowser.get())).GetOpenerWindowHandle()
184223
openerID = <int>hwnd
185224

@@ -192,33 +231,33 @@ class PyBrowser:
192231
def GetWindowID(self):
193232

194233
# Call this function to see whether Browser object is still valid, if topWindowID == 0 then invalid.
195-
return self.topWindowID
234+
return self.__topWindowID
196235

197236
def GetZoomLevel(self):
198237

199-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
238+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
200239
cdef double zoomLevel = (<CefBrowser*>(cefBrowser.get())).GetZoomLevel()
201240
return zoomLevel
202241

203242
def GoBack(self):
204243

205-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
244+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
206245
(<CefBrowser*>(cefBrowser.get())).GoBack()
207246

208247
def GoForward(self):
209248

210-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
249+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
211250
(<CefBrowser*>(cefBrowser.get())).GoForward()
212251

213252
def HasDocument(self):
214253

215-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
254+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
216255
return (<CefBrowser*>(cefBrowser.get())).HasDocument()
217256

218257

219258
def HidePopup(self):
220259

221-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
260+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
222261
(<CefBrowser*>(cefBrowser.get())).HidePopup()
223262

224263

@@ -230,13 +269,13 @@ class PyBrowser:
230269

231270
def SetZoomLevel(self, zoomLevel):
232271

233-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
272+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
234273
(<CefBrowser*>(cefBrowser.get())).SetZoomLevel(<double>float(zoomLevel))
235274

236275

237276
def ShowDevTools(self):
238277

239-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
278+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
240279
(<CefBrowser*>(cefBrowser.get())).ShowDevTools()
241280

242281

@@ -251,17 +290,17 @@ class PyBrowser:
251290

252291
def Reload(self):
253292

254-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
293+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
255294
(<CefBrowser*>(cefBrowser.get())).Reload()
256295

257296
def ReloadIgnoreCache(self):
258297

259-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
298+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
260299
(<CefBrowser*>(cefBrowser.get())).ReloadIgnoreCache()
261300

262301
def StopLoad(self):
263302

264-
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.innerWindowID))
303+
cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self.__innerWindowID))
265304
(<CefBrowser*>(cefBrowser.get())).StopLoad()
266305

267306
def IsPopup(self):

cefexample/README.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ icon.ico
4343

4444
CHANGELOG.
4545

46+
Version 0.30 released on ????.
47+
* Implemented JavascriptBindings.
48+
* Fixed application error when closing main window (Issue 2).
49+
4650
Version 0.26 released on 2012-07-08.
4751
* Implemented KeyboardHandler
4852
* cefadvanced.py: example of binding F12 key to open Developer tools, and F5 to refresh page.
@@ -61,3 +65,9 @@ Version 0.21 released on 2012-07-02.
6165

6266
Version 0.20 released on 2012-07-01.
6367
* First release that comes with real API.
68+
69+
Version 0.11 released on 2012-02-14.
70+
* Fixed hardcoded path to cefexample.html
71+
72+
Version 0.10 released on 2012-02-14.
73+
* This is just a proof of concept that python bindings to C++ api of CEF can be done with Cython.

cefexample/cefadvanced.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,21 @@
2929
<li>loading content from zip (optionally encrypted)
3030
</ul>
3131

32-
<!--<iframe src="cefsimple.html"></iframe>-->
32+
<iframe src="cefadvanced.html"></iframe>
3333
<!--<iframe src="cefsimple_onloaderror.html"></iframe>-->
3434

3535
<script>
3636
//frames["simple"].focus()
3737
</script>
3838

39+
<h3>Javascript bindings</h3>
40+
41+
<a href="javascript:PyTest1()">window.PyTest1()</a>,
42+
<a href="javascript:PyTest2()">window.PyTest2()</a>
43+
44+
<h3>Popups</h3>
45+
46+
<a href="javascript:window.open('cefadvanced.html', '', 'width=600,height=400')">window.open('cefadvanced.html')</a>
47+
3948
</body>
4049
</html>

0 commit comments

Comments
 (0)