Skip to content

Commit d075562

Browse files
CzarekCzarek
authored andcommitted
Implemented Load Handler in CEF Python 3. See the LoadHandler wiki page.
1 parent d380fe8 commit d075562

15 files changed

Lines changed: 708 additions & 143 deletions

File tree

cefpython/browser.pyx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ cdef class PyBrowser:
205205
"OnResourceRedirect", "GetAuthCredentials",
206206
"OnQuotaRequest", "GetCookieManager",
207207
"OnProtocolExecution"]
208+
# CefLoadHandler
209+
self.allowedClientCallbacks += ["OnLoadStart", "OnLoadEnd",
210+
"OnLoadError", "OnRendererProcessTerminated",
211+
"OnPluginCrashed"]
208212
if name not in self.allowedClientCallbacks:
209213
raise Exception("Browser.SetClientCallback() failed: unknown "
210214
"callback: %s" % name)

cefpython/cef3/client_handler/client_handler.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,81 @@ bool ClientHandler::OnCertificateError(
497497
cert_error, request_url, callback);
498498
// Default: return false;
499499
}
500+
501+
// --------------------------------------------------------------------------
502+
// CefLoadHandler
503+
// --------------------------------------------------------------------------
504+
505+
///
506+
// Implement this interface to handle events related to browser load status.
507+
// The methods of this class will be called on the UI thread.
508+
///
509+
510+
///
511+
// Called when the browser begins loading a frame. The |frame| value will
512+
// never be empty -- call the IsMain() method to check if this frame is the
513+
// main frame. Multiple frames may be loading at the same time. Sub-frames may
514+
// start or continue loading after the main frame load has ended. This method
515+
// may not be called for a particular frame if the load request for that frame
516+
// fails.
517+
///
518+
/*--cef()--*/
519+
void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
520+
CefRefPtr<CefFrame> frame) {
521+
REQUIRE_UI_THREAD();
522+
LoadHandler_OnLoadStart(browser, frame);
523+
}
524+
525+
///
526+
// Called when the browser is done loading a frame. The |frame| value will
527+
// never be empty -- call the IsMain() method to check if this frame is the
528+
// main frame. Multiple frames may be loading at the same time. Sub-frames may
529+
// start or continue loading after the main frame load has ended. This method
530+
// will always be called for all frames irrespective of whether the request
531+
// completes successfully.
532+
///
533+
/*--cef()--*/
534+
void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
535+
CefRefPtr<CefFrame> frame,
536+
int httpStatusCode) {
537+
REQUIRE_UI_THREAD();
538+
LoadHandler_OnLoadEnd(browser, frame, httpStatusCode);
539+
}
540+
541+
///
542+
// Called when the browser fails to load a resource. |errorCode| is the error
543+
// code number, |errorText| is the error text and and |failedUrl| is the URL
544+
// that failed to load. See net\base\net_error_list.h for complete
545+
// descriptions of the error codes.
546+
///
547+
/*--cef(optional_param=errorText)--*/
548+
void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
549+
CefRefPtr<CefFrame> frame,
550+
cef_errorcode_t errorCode,
551+
const CefString& errorText,
552+
const CefString& failedUrl) {
553+
REQUIRE_UI_THREAD();
554+
LoadHandler_OnLoadError(browser, frame, errorCode, errorText, failedUrl);
555+
}
556+
557+
///
558+
// Called when the render process terminates unexpectedly. |status| indicates
559+
// how the process terminated.
560+
///
561+
/*--cef()--*/
562+
void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
563+
cef_termination_status_t status) {
564+
REQUIRE_UI_THREAD();
565+
LoadHandler_OnRendererProcessTerminated(browser, status);
566+
}
567+
568+
///
569+
// Called when a plugin has crashed. |plugin_path| is the path of the plugin
570+
// that crashed.
571+
///
572+
/*--cef()--*/
573+
void ClientHandler::OnPluginCrashed(CefRefPtr<CefBrowser> browser,
574+
const CefString& plugin_path) {
575+
REQUIRE_UI_THREAD();
576+
LoadHandler_OnPluginCrashed(browser, plugin_path);
577+
}

cefpython/cef3/client_handler/client_handler.h

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class ClientHandler :
1515
public CefLifeSpanHandler,
1616
public CefDisplayHandler,
1717
public CefKeyboardHandler,
18-
public CefRequestHandler
18+
public CefRequestHandler,
19+
public CefLoadHandler
1920
{
2021
public:
2122
ClientHandler(){}
@@ -111,7 +112,7 @@ class ClientHandler :
111112
///
112113
/*--cef()--*/
113114
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
114-
return NULL;
115+
return this;
115116
}
116117

117118
///
@@ -477,6 +478,70 @@ class ClientHandler :
477478
const CefString& request_url,
478479
CefRefPtr<CefAllowCertificateErrorCallback> callback) OVERRIDE;
479480

481+
// --------------------------------------------------------------------------
482+
// CefLoadHandler
483+
// --------------------------------------------------------------------------
484+
485+
///
486+
// Implement this interface to handle events related to browser load status.
487+
// The methods of this class will be called on the UI thread.
488+
///
489+
490+
///
491+
// Called when the browser begins loading a frame. The |frame| value will
492+
// never be empty -- call the IsMain() method to check if this frame is the
493+
// main frame. Multiple frames may be loading at the same time. Sub-frames may
494+
// start or continue loading after the main frame load has ended. This method
495+
// may not be called for a particular frame if the load request for that frame
496+
// fails.
497+
///
498+
/*--cef()--*/
499+
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
500+
CefRefPtr<CefFrame> frame) OVERRIDE;
501+
502+
///
503+
// Called when the browser is done loading a frame. The |frame| value will
504+
// never be empty -- call the IsMain() method to check if this frame is the
505+
// main frame. Multiple frames may be loading at the same time. Sub-frames may
506+
// start or continue loading after the main frame load has ended. This method
507+
// will always be called for all frames irrespective of whether the request
508+
// completes successfully.
509+
///
510+
/*--cef()--*/
511+
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
512+
CefRefPtr<CefFrame> frame,
513+
int httpStatusCode) OVERRIDE;
514+
515+
///
516+
// Called when the browser fails to load a resource. |errorCode| is the error
517+
// code number, |errorText| is the error text and and |failedUrl| is the URL
518+
// that failed to load. See net\base\net_error_list.h for complete
519+
// descriptions of the error codes.
520+
///
521+
/*--cef(optional_param=errorText)--*/
522+
virtual void OnLoadError(CefRefPtr<CefBrowser> browser,
523+
CefRefPtr<CefFrame> frame,
524+
cef_errorcode_t errorCode,
525+
const CefString& errorText,
526+
const CefString& failedUrl) OVERRIDE;
527+
528+
///
529+
// Called when the render process terminates unexpectedly. |status| indicates
530+
// how the process terminated.
531+
///
532+
/*--cef()--*/
533+
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
534+
cef_termination_status_t status)
535+
OVERRIDE;
536+
537+
///
538+
// Called when a plugin has crashed. |plugin_path| is the path of the plugin
539+
// that crashed.
540+
///
541+
/*--cef()--*/
542+
virtual void OnPluginCrashed(CefRefPtr<CefBrowser> browser,
543+
const CefString& plugin_path) OVERRIDE;
544+
480545
private:
481546

482547
// Include the default reference counting implementation.

cefpython/cef3/include/cef_load_handler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class CefLoadHandler : public virtual CefBase {
8686
/*--cef(optional_param=errorText)--*/
8787
virtual void OnLoadError(CefRefPtr<CefBrowser> browser,
8888
CefRefPtr<CefFrame> frame,
89-
ErrorCode errorCode,
89+
cef_errorcode_t errorCode,
9090
const CefString& errorText,
9191
const CefString& failedUrl) {}
9292

@@ -96,7 +96,7 @@ class CefLoadHandler : public virtual CefBase {
9696
///
9797
/*--cef()--*/
9898
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
99-
TerminationStatus status) {}
99+
cef_termination_status_t status) {}
100100

101101
///
102102
// Called when a plugin has crashed. |plugin_path| is the path of the plugin

cefpython/cef3/linux/binaries_32bit/wxpython.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,5 +400,61 @@ <h3>Cookie tests</h3>
400400
<br><br>
401401

402402

403+
404+
405+
<h3>Load Handler</h3>
406+
<pre>
407+
def OnLoadStart(self, browser, frame):
408+
print("LoadHandler::OnLoadStart()")
409+
print("frame url = %s" % frame.GetUrl()[:70])
410+
</pre>
411+
See messages in the console.
412+
413+
<pre>
414+
def OnLoadEnd(self, browser, frame, httpStatusCode):
415+
print("LoadHandler::OnLoadEnd()")
416+
print("frame url = %s" % frame.GetUrl()[:70])
417+
# For file:// urls the status code = 0
418+
print("http status code = %s" % httpStatusCode)
419+
</pre>
420+
See messages in the console.
421+
422+
<pre>
423+
def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl):
424+
print("LoadHandler::OnLoadError()")
425+
print("frame url = %s" % frame.GetUrl()[:70])
426+
print("error code = %s" % errorCode)
427+
print("error text = %s" % errorTextList[0])
428+
print("failed url = %s" % failedUrl)
429+
customErrorMessage = "My custom error message!"
430+
frame.LoadUrl("data:text/html,%s" % customErrorMessage)
431+
</pre>
432+
Try this:
433+
<a href="http://www.non-existent.nono/">
434+
http://www.non-existent.nono/</a>
435+
436+
<pre>
437+
def OnRendererProcessTerminated(self, browser, status):
438+
print("LoadHandler::OnRendererProcessTerminated()")
439+
statuses = {
440+
cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION",
441+
cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED",
442+
cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED"
443+
}
444+
statusName = "Unknown"
445+
if status in statuses:
446+
statusName = statuses[status]
447+
print("status = %s" % statusName)
448+
</pre>
449+
Try to terminate the "subprocess.exe" renderer process through
450+
process/task manager.
451+
452+
<pre>
453+
def OnPluginCrashed(self, browser, pluginPath):
454+
print("LoadHandler::OnPluginCrashed()")
455+
print("plugin path = %s" % pluginPath)
456+
</pre>
457+
No test for that yet.
458+
403459
</body>
404460
</html>

cefpython/cef3/linux/binaries_32bit/wxpython.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,44 @@ def _OnCertificateError(self, certError, requestUrl, callback):
381381
return True
382382
return False
383383

384+
# -------------------------------------------------------------------------
385+
# LoadHandler
386+
# -------------------------------------------------------------------------
387+
def OnLoadStart(self, browser, frame):
388+
print("LoadHandler::OnLoadStart()")
389+
print("frame url = %s" % frame.GetUrl()[:70])
390+
391+
def OnLoadEnd(self, browser, frame, httpStatusCode):
392+
print("LoadHandler::OnLoadEnd()")
393+
print("frame url = %s" % frame.GetUrl()[:70])
394+
# For file:// urls the status code = 0
395+
print("http status code = %s" % httpStatusCode)
396+
397+
def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl):
398+
print("LoadHandler::OnLoadError()")
399+
print("frame url = %s" % frame.GetUrl()[:70])
400+
print("error code = %s" % errorCode)
401+
print("error text = %s" % errorTextList[0])
402+
print("failed url = %s" % failedUrl)
403+
customErrorMessage = "My custom error message!"
404+
frame.LoadUrl("data:text/html,%s" % customErrorMessage)
405+
406+
def OnRendererProcessTerminated(self, browser, status):
407+
print("LoadHandler::OnRendererProcessTerminated()")
408+
statuses = {
409+
cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION",
410+
cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED",
411+
cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED"
412+
}
413+
statusName = "Unknown"
414+
if status in statuses:
415+
statusName = statuses[status]
416+
print("status = %s" % statusName)
417+
418+
def OnPluginCrashed(self, browser, pluginPath):
419+
print("LoadHandler::OnPluginCrashed()")
420+
print("plugin path = %s" % pluginPath)
421+
384422
class MyApp(wx.App):
385423
timer = None
386424
timerID = 1

cefpython/cef3/linux/binaries_64bit/wxpython.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,5 +400,61 @@ <h3>Cookie tests</h3>
400400
<br><br>
401401

402402

403+
404+
405+
<h3>Load Handler</h3>
406+
<pre>
407+
def OnLoadStart(self, browser, frame):
408+
print("LoadHandler::OnLoadStart()")
409+
print("frame url = %s" % frame.GetUrl()[:70])
410+
</pre>
411+
See messages in the console.
412+
413+
<pre>
414+
def OnLoadEnd(self, browser, frame, httpStatusCode):
415+
print("LoadHandler::OnLoadEnd()")
416+
print("frame url = %s" % frame.GetUrl()[:70])
417+
# For file:// urls the status code = 0
418+
print("http status code = %s" % httpStatusCode)
419+
</pre>
420+
See messages in the console.
421+
422+
<pre>
423+
def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl):
424+
print("LoadHandler::OnLoadError()")
425+
print("frame url = %s" % frame.GetUrl()[:70])
426+
print("error code = %s" % errorCode)
427+
print("error text = %s" % errorTextList[0])
428+
print("failed url = %s" % failedUrl)
429+
customErrorMessage = "My custom error message!"
430+
frame.LoadUrl("data:text/html,%s" % customErrorMessage)
431+
</pre>
432+
Try this:
433+
<a href="http://www.non-existent.nono/">
434+
http://www.non-existent.nono/</a>
435+
436+
<pre>
437+
def OnRendererProcessTerminated(self, browser, status):
438+
print("LoadHandler::OnRendererProcessTerminated()")
439+
statuses = {
440+
cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION",
441+
cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED",
442+
cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED"
443+
}
444+
statusName = "Unknown"
445+
if status in statuses:
446+
statusName = statuses[status]
447+
print("status = %s" % statusName)
448+
</pre>
449+
Try to terminate the "subprocess.exe" renderer process through
450+
process/task manager.
451+
452+
<pre>
453+
def OnPluginCrashed(self, browser, pluginPath):
454+
print("LoadHandler::OnPluginCrashed()")
455+
print("plugin path = %s" % pluginPath)
456+
</pre>
457+
No test for that yet.
458+
403459
</body>
404460
</html>

0 commit comments

Comments
 (0)