Skip to content

Commit 6bb2d4e

Browse files
committed
Add javascript_erors.py and ondomready.py snippets (cztomczak#403)
1 parent 2415a8f commit 6bb2d4e

File tree

6 files changed

+140
-20
lines changed

6 files changed

+140
-20
lines changed

docs/Tutorial.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ basics. This tutorial will discuss the three featured examples:
99
[hello_world.py](../examples/hello_world.py),
1010
[tutorial.py](../examples/tutorial.py)
1111
and [screenshot.py](../examples/screenshot.py). There are many
12-
more examples that you can find in the [README-examples.md](../examples/README-examples.md)
12+
more examples that you can find in the
13+
[README-examples.md](../examples/README-examples.md)
1314
file, but these examples are out of scope for this tutorial.
1415

1516

examples/README-examples.md

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ Table of contents:
44
* [Hello World!](#hello-world)
55
* [Supported examples](#supported-examples)
66
* [Featured](#featured)
7-
* [GUI frameworks](#gui-frameworks)
87
* [Snippets](#snippets)
8+
* [GUI frameworks](#gui-frameworks)
99
* [Build executable with PyInstaller](#build-executable-with-pyinstaller)
1010
* [Unit tests](#unit-tests)
1111
* [Other examples](#other-examples)
@@ -42,8 +42,31 @@ workarounds.
4242
discussed in great details in Tutorial in the [Off-screen rendering](../docs/Tutorial.md#off-screen-rendering)
4343
section.
4444

45+
46+
### Snippets
47+
48+
See small code snippets that show various CEF features in the
49+
[examples/snippets/](snippets/) directory:
50+
51+
- [javascript_bindings.py](snippets/javascript_bindings.py) - Communicate
52+
between Python and Javascript asynchronously using
53+
inter-process messaging with the use of Javascript Bindings.
54+
- [javascript_errors.py](snippets/javascript_errors.py) - Two ways for
55+
intercepting Javascript errors.
56+
- [mouse_clicks.py](snippets/mouse_clicks.py) - Perform mouse clicks
57+
and mouse movements programmatically.
58+
- [network_cookies.py](snippets/network_cookies.py) - Implement
59+
interfaces to block or allow cookies over network requests.
60+
- [onbeforeclose.py](snippets/onbeforeclose.py) - Implement interface
61+
to execute custom code before browser window closes.
62+
- [ondomready.py](snippets/ondomready.py) - Execute custom Python code
63+
on a web page as soon as DOM is ready.
64+
65+
4566
### GUI frameworks
4667

68+
Examples of embedding CEF browser using various GUI frameworks:
69+
4770
- [gtk2.py](gtk2.py): example for [PyGTK](http://www.pygtk.org/)
4871
library (GTK 2)
4972
- [gtk3.py](gtk3.py): example for [PyGObject / PyGI](https://wiki.gnome.org/Projects/PyGObject)
@@ -64,22 +87,6 @@ workarounds.
6487
toolkit. This example implements High DPI support on Windows.
6588

6689

67-
### Snippets
68-
69-
See small code snippets that test various features in the
70-
[examples/snippets/](snippets/) directory:
71-
72-
- [javascript_bindings.py](snippets/javascript_bindings.py) - Communicate
73-
between Python and Javascript asynchronously using
74-
inter-process messaging with the use of Javascript Bindings.
75-
- [mouse_clicks.py](snippets/mouse_clicks.py) - Perform mouse clicks
76-
and mouse movements programmatically.
77-
- [network_cookies.py](snippets/network_cookies.py) - Implement
78-
interfaces to block or allow cookies over network requests.
79-
- [onbeforeclose.py](snippets/onbeforeclose.py) - Implement interface
80-
to execute custom code before browser window closes.
81-
82-
8390
### Build executable with PyInstaller
8491

8592
- [PyInstaller example](pyinstaller/README-pyinstaller.md):

examples/snippets/javascript_bindings.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
</style>
1818
<script>
1919
function print(msg) {
20-
console.log(msg+" [JS]");
2120
document.getElementById("console").innerHTML += msg+"<br>";
2221
}
2322
function js_function(value) {
@@ -41,7 +40,7 @@
4140
def main():
4241
cef.Initialize()
4342
browser = cef.CreateBrowserSync(url=cef.GetDataUrl(g_htmlcode),
44-
window_title="OnBeforeClose")
43+
window_title="Javascript Bindings")
4544
browser.SetClientHandler(LifespanHandler())
4645
bindings = cef.JavascriptBindings()
4746
bindings.SetFunction("py_function", py_function)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
Two ways for intercepting Javascript errors:
3+
1. window.onerror event in Javascript
4+
2. DisplayHandler.OnConsoleMessage in Python
5+
"""
6+
7+
from cefpython3 import cefpython as cef
8+
9+
g_htmlcode = """
10+
<!doctype html>
11+
<html>
12+
<head>
13+
<style>
14+
body, html {
15+
font-family: Arial;
16+
font-size: 11pt;
17+
}
18+
</style>
19+
<script>
20+
function print(msg) {
21+
document.getElementById("console").innerHTML += msg+"<br>";
22+
}
23+
window.onerror = function(message, source, lineno, colno, error) {
24+
print("[JS:window.onerror] "+error+" (line "+lineno+")");
25+
// Return false so that default event handler is fired and
26+
// OnConsoleMessage can also intercept this error.
27+
return false;
28+
};
29+
window.onload = function() {
30+
forceError();
31+
};
32+
</script>
33+
</head>
34+
<body>
35+
<h1>Javascript Errors</h1>
36+
<div id=console></div>
37+
</body>
38+
</html>
39+
"""
40+
41+
42+
def main():
43+
cef.Initialize()
44+
browser = cef.CreateBrowserSync(url=cef.GetDataUrl(g_htmlcode),
45+
window_title="Javascript Errors")
46+
browser.SetClientHandler(DisplayHandler())
47+
cef.MessageLoop()
48+
cef.Shutdown()
49+
50+
51+
class DisplayHandler(object):
52+
def OnConsoleMessage(self, browser, message, line, **_):
53+
if "error" in message.lower() or "uncaught" in message.lower():
54+
logmsg = "[Py:OnConsoleMessage] {message} (line {line})" \
55+
.format(message=message, line=line)
56+
print(logmsg)
57+
browser.ExecuteFunction("print", logmsg)
58+
59+
60+
if __name__ == '__main__':
61+
main()

examples/snippets/ondomready.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""
2+
Execute custom Python code on a web page as soon as DOM is ready.
3+
Implements a custom "_OnDomReady" event in the LifespanHandler object.
4+
"""
5+
6+
from cefpython3 import cefpython as cef
7+
8+
9+
def main():
10+
cef.Initialize()
11+
browser = cef.CreateBrowserSync(url="https://www.google.com/",
12+
window_title="_OnDomReady event")
13+
lifespan_handler = LifespanHandler(browser)
14+
browser.SetClientHandler(lifespan_handler)
15+
bindings = cef.JavascriptBindings()
16+
bindings.SetFunction("LifespanHandler_OnDomReady",
17+
lifespan_handler["_OnDomReady"])
18+
browser.SetJavascriptBindings(bindings)
19+
cef.MessageLoop()
20+
del lifespan_handler
21+
del browser
22+
cef.Shutdown()
23+
24+
25+
class LifespanHandler(object):
26+
def __init__(self, browser):
27+
self.browser = browser
28+
29+
def __getitem__(self, key):
30+
return getattr(self, key)
31+
32+
def OnLoadStart(self, browser, **_):
33+
browser.ExecuteJavascript("""
34+
if (document.readyState === "complete") {
35+
LifespanHandler_OnDomReady();
36+
} else {
37+
document.addEventListener("DOMContentLoaded", function() {
38+
LifespanHandler_OnDomReady();
39+
});
40+
}
41+
""")
42+
43+
def _OnDomReady(self):
44+
print("DOM is ready!")
45+
self.browser.ExecuteFunction("alert",
46+
"Message from Python: DOM is ready!")
47+
48+
49+
if __name__ == '__main__':
50+
main()

src/cef_v59..v66_changes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ NEW FEATURES
8383
+ network_cookies.py
8484
+ mouse_clicks.py
8585
+ javascript_bindings.py
86+
+ javascript_errors.py
87+
+ ondomready.py
8688
+ cef.GetDataUrl
8789

8890
internal/cef_types.h

0 commit comments

Comments
 (0)