22# License: New BSD License.
33# Website: http://code.google.com/p/cefpython/
44
5- class Browser :
6-
7- windowID = 0
8-
9- def __init__ (self , windowID ):
10-
11- self .windowID = windowID
12- assert win32gui.IsWindow(windowID), " Invalid window handle (windowID)"
13- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(self .windowID)
14- assert < void * > cefBrowser != NULL , " CefBrowser not found for this window handle (windowID)"
5+ # Global variables.
156
16- def GetWindowID (self ):
7+ cdef map [int , CefRefPtr[CefBrowser]] __cefBrowsers # innerWindowID : browser
8+ __pyBrowsers = {}
179
18- # Call this function to see whether Browser object is still valid, if windowID == 0 then invalid.
19- return self .windowID
10+ # This dictionary list of popup browsers is never cleaned, it may contain old inner
11+ # window ID's as keys. Popup window might be created via window.open() and
12+ # we have no control over it. This list of popup browsers is for GetPyBrowserByCefBrowser()
13+ # so that we cache PyBrowser() objects, as there might a lot of LoadHandler events
14+ # that call this function and instantiating a new class for each of these events is too much overhead.
15+ __popupPyBrowsers = {} # Just a cache.
2016
21- def GetOpenerWindowID ( self ):
17+ __browserInnerWindows = {} # topWindowID : innerWindowID (CefBrowser.GetWindowHandle)
2218
23- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
24- cdef HWND hwnd = (< CefBrowser* > (cefBrowser.get())).GetOpenerWindowHandle()
25- openerID = < int > hwnd
19+ # PyBrowser.
20+
21+ class PyBrowser :
22+
23+ topWindowID = 0
24+ innerWindowID = 0
25+ handlers = {}
26+
27+ def __init__ (self , topWindowID , innerWindowID , handlers ):
2628
27- if openerID:
28- assert win32gui.IsWindow(openerID), " CefBrowser.GetOpenerWindowHandle() returned invalid handle"
29- return openerID
29+ self .topWindowID = topWindowID
30+ self .innerWindowID = innerWindowID
3031
31- return None
32+ assert win32gui.IsWindow(innerWindowID), " Invalid window handle (innerWindowID)"
33+
34+ cdef CefRefPtr[CefBrowser] cefBrowser
35+ if - 1 != self .topWindowID:
36+
37+ # We do this check only for non-popup windows.
38+
39+ # Functions in this class can be called only if topWindowID is set, as they call
40+ # GetCefBrowserByInnerWindowID() and this one uses __cefBrowsers[] which
41+ # are set only when creating Browser objects explicitily and topWindowID's are
42+ # provided.
43+
44+ # Handlers are empty for popup windows, so LoadHandler() and others won't
45+ # call any of the functions in this object, they just need the object to check
46+ # whether handler exists for given event.
47+
48+ # This object is instantiated because Handlers are binded to ClientHandler which
49+ # is a global object and is automatically inherited by implicitily created popup
50+ # browser windows.
51+
52+ cefBrowser = GetCefBrowserByInnerWindowID(self .innerWindowID)
53+ assert < void * > cefBrowser != NULL , " CefBrowser not found for this innerWindowID: %s " % self .innerWindowID
54+
55+ self .__checkHandlers(handlers)
56+ self .handlers = handlers
3257
33- def CloseBrowser (self ):
58+ def __checkHandlers (self , handlers ):
3459
35- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
36- (< CefBrowser* > (cefBrowser.get())).ParentWindowWillClose()
37- (< CefBrowser* > (cefBrowser.get())).CloseBrowser()
38- __cefBrowsers.erase(< int > self .windowID)
39- del __pyBrowsers[self .windowID]
40- self .windowID = 0
60+ allowedHandlers = []
61+
62+ # CefLoadHandler.
63+ allowedHandlers += [" OnLoadEnd" , " OnLoadError" , " OnLoadStart" ]
4164
42- def ShowDevTools (self ):
65+ for key in handlers:
66+ if key not in allowedHandlers:
67+ raise Exception (" Unknown handler: %s , mistyped?" % key)
4368
44- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID( self .windowID))
45- ( < CefBrowser * > (cefBrowser.get())).ShowDevTools()
69+ # Internal.
70+ def GetHandler ( self , name ):
4671
47- def CloseDevTools ( self ) :
48-
49- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID( self .windowID))
50- ( < CefBrowser * > (cefBrowser.get())).CloseDevTools()
72+ if name in self .handlers :
73+ return self .handlers[name]
74+
75+ # PUBLIC API.
5176
5277 def CanGoBack (self ):
5378
54- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID (self .windowID ))
79+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID (self .innerWindowID ))
5580 cdef cbool canGoBack = (< CefBrowser* > (cefBrowser.get())).CanGoBack()
5681 return canGoBack
5782
58- def GoBack (self ):
59-
60- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
61- (< CefBrowser* > (cefBrowser.get())).GoBack()
62-
6383 def CanGoForward (self ):
6484
65- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID (self .windowID ))
85+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID (self .innerWindowID ))
6686 cdef cbool canGoForward = (< CefBrowser* > (cefBrowser.get())).CanGoForward()
6787 return canGoForward
6888
69- def GoForward (self ):
70-
71- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
72- (< CefBrowser* > (cefBrowser.get())).GoForward()
73-
74- def Reload (self ):
75-
76- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
77- (< CefBrowser* > (cefBrowser.get())).Reload()
89+ def ClearHistory (self ):
7890
79- def ReloadIgnoreCache (self ):
91+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
92+ (< CefBrowser* > (cefBrowser.get())).ClearHistory()
8093
81- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
82- (< CefBrowser* > (cefBrowser.get())).ReloadIgnoreCache()
83-
84- def StopLoad (self ):
94+ def CloseBrowser (self ):
8595
86- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
87- (< CefBrowser* > (cefBrowser.get())).StopLoad()
96+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
97+ __cefBrowsers.erase(< int > self .innerWindowID)
98+ del __pyBrowsers[self .innerWindowID]
99+
100+ # -1 == Popup, the window wasn't created by us, so we don't have the topWindowID.
101+ # See -1 value in GetPyBrowserByCefBrowser().
102+ if - 1 != self .topWindowID:
103+ del __browserInnerWindows[self .topWindowID]
88104
89- def IsPopup (self ):
105+ self .topWindowID = 0
106+ self .innerWindowID = 0
107+ (< CefBrowser* > (cefBrowser.get())).ParentWindowWillClose()
108+ (< CefBrowser* > (cefBrowser.get())).CloseBrowser()
90109
91- pass
110+ def CloseDevTools (self ):
111+
112+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
113+ (< CefBrowser* > (cefBrowser.get())).CloseDevTools()
92114
93- def HasDocument (self ):
115+ def Find (self , identifier , searchText , forward , matchCase , findNext ):
94116
95- pass
117+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID( self .innerWindowID))
96118
97- def GetMainFrame (self ):
119+ cdef CefString cefSearchText
120+ cefSearchText.FromASCII(< char * > searchText)
98121
99- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
100-
101- cdef CefRefPtr[CefFrame] cefFrame = (< CefBrowser* > (cefBrowser.get())).GetMainFrame()
122+ (< CefBrowser* > (cefBrowser.get())).Find(
123+ < int > identifier, cefSearchText, < cbool> bool (forward), < cbool> bool (matchCase), < cbool> bool (findNext))
102124
103- global __pyFrames
104- cdef long long frameID
105- if < void * > cefFrame != NULL and < CefFrame* > (cefFrame.get()):
106- frameID = (< CefFrame* > (cefFrame.get())).GetIdentifier()
107- __cefFrames[frameID] = cefFrame
108- pyFrameID = long (frameID)
109- print " pyFrameID: %s " % pyFrameID
110- if pyFrameID in __pyFrames:
111- return __pyFrames[pyFrameID]
112- __pyFrames[pyFrameID] = Frame(pyFrameID)
113- return __pyFrames[pyFrameID]
114-
115125 def GetFocusedFrame (self ):
116126
117127 assert CurrentlyOn(TID_UI), " Browser.GetFocusedFrame() should only be called on the UI thread"
118- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID(self .windowID))
119-
128+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
120129 cdef CefRefPtr[CefFrame] cefFrame = (< CefBrowser* > (cefBrowser.get())).GetFocusedFrame()
121-
122- global __pyFrames
123- cdef cef_types.int64 frameID
124- if < void * > cefFrame != NULL and < CefFrame* > (cefFrame.get()):
125- frameID = (< CefFrame* > (cefFrame.get())).GetIdentifier()
126- __cefFrames[frameID] = cefFrame
127- pyFrameID = long (frameID)
128- print " pyFrameID: %s " % pyFrameID
129- if pyFrameID in __pyFrames:
130- return __pyFrames[pyFrameID]
131- __pyFrames[pyFrameID] = Frame(pyFrameID)
132- return __pyFrames[pyFrameID]
133130
131+ return GetPyFrameByCefFrame(cefFrame)
132+
134133 def GetFrame (self , name ):
135134
136- assert CurrentlyOn(TID_UI), " Browser.GetFocusedFrame () should only be called on the UI thread"
137- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID (self .windowID ))
135+ assert CurrentlyOn(TID_UI), " Browser.GetFrame () should only be called on the UI thread"
136+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID (self .innerWindowID ))
138137
139138 cdef CefString cefName
140139 cefName.FromASCII(< char * > name)
141140 cdef CefRefPtr[CefFrame] cefFrame = (< CefBrowser* > (cefBrowser.get())).GetFrame(cefName)
142-
143- global __pyFrames
144- cdef cef_types.int64 frameID
145- if < void * > cefFrame != NULL and < CefFrame* > (cefFrame.get()):
146- frameID = (< CefFrame* > (cefFrame.get())).GetIdentifier()
147- __cefFrames[frameID] = cefFrame
148- pyFrameID = long (frameID)
149- if pyFrameID in __pyFrames:
150- return __pyFrames[pyFrameID]
151- __pyFrames[pyFrameID] = Frame(pyFrameID)
152- return __pyFrames[pyFrameID]
141+
142+ return GetPyFrameByCefFrame(cefFrame) # may return None.
153143
154144 def GetFrameNames (self ):
155145
156- # Seems not to work! cefNames.size() is always 0
157- # Tried on iframe and frameset.
158-
159146 assert CurrentlyOn(TID_UI), " Browser.GetFrameNames() should only be called on the UI thread"
160- cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByWindowID(CheckWindowID (self .windowID ))
147+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID (self .innerWindowID ))
161148
162149 cdef vector[CefString] cefNames
163150 (< CefBrowser* > (cefBrowser.get())).GetFrameNames(cefNames)
164- if __debug: print " GetFrameNames() vector size: %s " % cefNames.size()
165151
166152 names = []
167153 cdef vector[CefString].iterator iterator = cefNames.begin()
168154 cdef CefString cefString
169155 while iterator != cefNames.end():
170156 cefString = deref(iterator)
171- names.push (CefStringToPyString(cefString))
157+ names.append (CefStringToPyString(cefString))
172158 preinc(iterator)
173159
174160 return names
175161
176- cdef GetPyFrame():
177- pass
162+ def GetMainFrame (self ):
163+
164+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
165+ cdef CefRefPtr[CefFrame] cefFrame = (< CefBrowser* > (cefBrowser.get())).GetMainFrame()
166+
167+ return GetPyFrameByCefFrame(cefFrame)
168+
169+ def GetOpenerWindowID (self ):
170+
171+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
172+ cdef HWND hwnd = (< CefBrowser* > (cefBrowser.get())).GetOpenerWindowHandle()
173+ openerID = < int > hwnd
174+
175+ if openerID:
176+ assert win32gui.IsWindow(openerID), " CefBrowser.GetOpenerWindowHandle() returned invalid handle"
177+ return openerID
178+
179+ return None
180+
181+ def GetWindowID (self ):
182+
183+ # Call this function to see whether Browser object is still valid, if topWindowID == 0 then invalid.
184+ return self .topWindowID
185+
186+ def GetZoomLevel (self ):
187+
188+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
189+ cdef double zoomLevel = (< CefBrowser* > (cefBrowser.get())).GetZoomLevel()
190+ return zoomLevel
191+
192+ def GoBack (self ):
193+
194+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
195+ (< CefBrowser* > (cefBrowser.get())).GoBack()
196+
197+ def GoForward (self ):
198+
199+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
200+ (< CefBrowser* > (cefBrowser.get())).GoForward()
201+
202+ def HasDocument (self ):
203+
204+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
205+ return (< CefBrowser* > (cefBrowser.get())).HasDocument()
206+
207+
208+ def HidePopup (self ):
209+
210+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
211+ (< CefBrowser* > (cefBrowser.get())).HidePopup()
212+
213+
214+
215+ # ----------------------
216+
217+
218+
219+
220+ def SetZoomLevel (self , zoomLevel ):
221+
222+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
223+ (< CefBrowser* > (cefBrowser.get())).SetZoomLevel(< double > float (zoomLevel))
224+
225+
226+ def ShowDevTools (self ):
227+
228+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
229+ (< CefBrowser* > (cefBrowser.get())).ShowDevTools()
230+
231+
232+
233+
234+
235+
236+
237+
238+
239+
240+
241+ def Reload (self ):
242+
243+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
244+ (< CefBrowser* > (cefBrowser.get())).Reload()
245+
246+ def ReloadIgnoreCache (self ):
247+
248+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
249+ (< CefBrowser* > (cefBrowser.get())).ReloadIgnoreCache()
250+
251+ def StopLoad (self ):
252+
253+ cdef CefRefPtr[CefBrowser] cefBrowser = GetCefBrowserByInnerWindowID(CheckInnerWindowID(self .innerWindowID))
254+ (< CefBrowser* > (cefBrowser.get())).StopLoad()
255+
256+ def IsPopup (self ):
257+
258+ pass
259+
260+
261+
0 commit comments