diff --git a/README.md b/README.md index 8e6259bc..9ecad822 100644 --- a/README.md +++ b/README.md @@ -469,6 +469,7 @@ Additional information for v31.2 release: * [GetBrowserByIdentifier](api/cefpython.md#getbrowserbyidentifier) * [GetBrowserByWindowHandle](api/cefpython.md#getbrowserbywindowhandle) * [GetCommandLineSwitch](api/cefpython.md#getcommandlineswitch) + * [GetDataUrl](api/cefpython.md#getdataurl) * [GetGlobalClientCallback](api/cefpython.md#getglobalclientcallback) * [GetModuleDirectory](api/cefpython.md#getmoduledirectory) * [GetVersion](api/cefpython.md#getversion) diff --git a/api/API-index.md b/api/API-index.md index d5e3efcb..9535cb5b 100644 --- a/api/API-index.md +++ b/api/API-index.md @@ -157,6 +157,7 @@ * [GetBrowserByIdentifier](cefpython.md#getbrowserbyidentifier) * [GetBrowserByWindowHandle](cefpython.md#getbrowserbywindowhandle) * [GetCommandLineSwitch](cefpython.md#getcommandlineswitch) + * [GetDataUrl](cefpython.md#getdataurl) * [GetGlobalClientCallback](cefpython.md#getglobalclientcallback) * [GetModuleDirectory](cefpython.md#getmoduledirectory) * [GetVersion](cefpython.md#getversion) diff --git a/api/cefpython.md b/api/cefpython.md index 239bf400..a876bd69 100644 --- a/api/cefpython.md +++ b/api/cefpython.md @@ -16,6 +16,7 @@ Table of contents: * [GetBrowserByIdentifier](#getbrowserbyidentifier) * [GetBrowserByWindowHandle](#getbrowserbywindowhandle) * [GetCommandLineSwitch](#getcommandlineswitch) + * [GetDataUrl](#getdataurl) * [GetGlobalClientCallback](#getglobalclientcallback) * [GetModuleDirectory](#getmoduledirectory) * [GetVersion](#getversion) @@ -140,6 +141,20 @@ Get browser by outer or inner window handle. An outer window handle is the one t Returns the [CommandLineSwitches](CommandLineSwitches.md) switch that was passed to Initialize(). Returns None if key is not found. +### GetDataUrl + +| Parameter | Type | +| --- | --- | +| data | string | +| mediatype="html" (optional) | string | +| __Return__ | object | + +Convert data to a Data URL. Only "html" media type is currently supported. + +See: +https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs + + ### GetGlobalClientCallback | Parameter | Type | diff --git a/examples/README-examples.md b/examples/README-examples.md index c4e98961..0f0ef9a4 100644 --- a/examples/README-examples.md +++ b/examples/README-examples.md @@ -67,7 +67,17 @@ workarounds. ### Snippets See small code snippets that test various features in the -[examples/snippets/](snippets/) directory. +[examples/snippets/](snippets/) directory: + +- [javascript_bindings.py](snippets/javascript_bindings.py) - Communicate + between Python and Javascript asynchronously using + inter-process messaging with the use of Javascript Bindings. +- [mouse_clicks.py](snippets/mouse_clicks.py) - Perform mouse clicks + and mouse movements programmatically. +- [network_cookies.py](snippets/network_cookies.py) - Implement + interfaces to block or allow cookies over network requests. +- [onbeforeclose.py](snippets/onbeforeclose.py) - Implement interface + to execute custom code before browser window closes. ### Build executable with PyInstaller diff --git a/examples/pyinstaller/hook-cefpython3.py b/examples/pyinstaller/hook-cefpython3.py index e36c8ed3..d30a2308 100644 --- a/examples/pyinstaller/hook-cefpython3.py +++ b/examples/pyinstaller/hook-cefpython3.py @@ -162,6 +162,7 @@ def get_cefpython3_datas(): # TODO: Write a tool script that would find such imports in # .pyx files automatically. hiddenimports = [ + "base64", "codecs", "copy", "datetime", diff --git a/examples/snippets/javascript_bindings.py b/examples/snippets/javascript_bindings.py new file mode 100644 index 00000000..7c7dccc5 --- /dev/null +++ b/examples/snippets/javascript_bindings.py @@ -0,0 +1,70 @@ +""" +Communicate between Python and Javascript asynchronously using +inter-process messaging with the use of Javascript Bindings. +""" + +from cefpython3 import cefpython as cef + +g_htmlcode = """ + + + + + + + +

Javascript Bindings

+
+ + +""" + + +def main(): + cef.Initialize() + browser = cef.CreateBrowserSync(url=cef.GetDataUrl(g_htmlcode), + window_title="OnBeforeClose") + browser.SetClientHandler(LifespanHandler()) + bindings = cef.JavascriptBindings() + bindings.SetFunction("py_function", py_function) + bindings.SetFunction("py_callback", py_callback) + browser.SetJavascriptBindings(bindings) + cef.MessageLoop() + del browser + cef.Shutdown() + + +def py_function(value, js_callback): + print("Value sent from Javascript: "+value) + js_callback.Call("I am a Python string #2", py_callback) + + +def py_callback(value): + print("Value sent from Javascript: "+value) + + +class LifespanHandler(object): + def OnLoadEnd(self, browser, **_): + browser.ExecuteFunction("js_function", "I am a Python string #1") + + +if __name__ == '__main__': + main() diff --git a/examples/snippets/mouse_clicks.py b/examples/snippets/mouse_clicks.py index fcdd5280..e8ace36a 100644 --- a/examples/snippets/mouse_clicks.py +++ b/examples/snippets/mouse_clicks.py @@ -43,7 +43,7 @@ class LifespanHandler(object): def OnLoadEnd(self, browser, **_): # Execute function with a delay of 1 second after page # has completed loading. - print("Page completed loading") + print("Page loading is complete") cef.PostDelayedTask(cef.TID_UI, 1000, click_after_1_second, browser) diff --git a/examples/snippets/network_cookies.py b/examples/snippets/network_cookies.py index 55a71ec0..c3631cff 100644 --- a/examples/snippets/network_cookies.py +++ b/examples/snippets/network_cookies.py @@ -30,7 +30,7 @@ def CanGetCookies(self, frame, request, **_): print("-- CanGetCookies #"+str(self.getcount)) print("url="+request.GetUrl()[0:80]) print("") - # Return True to allow reading cookies and False to block + # Return True to allow reading cookies or False to block return True def CanSetCookie(self, frame, request, cookie, **_): @@ -43,7 +43,7 @@ def CanSetCookie(self, frame, request, cookie, **_): print("Name="+cookie.GetName()) print("Value="+cookie.GetValue()) print("") - # Return True to allow setting cookie and False to block + # Return True to allow setting cookie or False to block return True diff --git a/src/cef_v59..v66_changes.txt b/src/cef_v59..v66_changes.txt index fdf96cb2..f78800d3 100644 --- a/src/cef_v59..v66_changes.txt +++ b/src/cef_v59..v66_changes.txt @@ -82,6 +82,8 @@ NEW FEATURES + onbeforeclose.py + network_cookies.py + mouse_clicks.py + + javascript_bindings.py ++ cef.GetDataUrl internal/cef_types.h + cef_log_severity_t: new key LOGSEVERITY_DEBUG (no need to expose, diff --git a/src/cefpython.pyx b/src/cefpython.pyx index 5a526bcd..1631636f 100644 --- a/src/cefpython.pyx +++ b/src/cefpython.pyx @@ -134,6 +134,8 @@ import datetime import random # noinspection PyUnresolvedReferences import struct +# noinspection PyUnresolvedReferences +import base64 # Must use compile-time condition instead of checking sys.version_info.major # otherwise results in "ImportError: cannot import name urlencode" strange @@ -1023,3 +1025,9 @@ cpdef dict GetVersion(): cpdef LoadCrlSetsFile(py_string path): CefLoadCRLSetsFile(PyToCefStringValue(path)) + +cpdef GetDataUrl(data, mediatype="html"): + html = data.encode("utf-8", "replace") + b64 = base64.b64encode(html).decode("utf-8", "replace") + ret = "data:text/html;base64,{data}".format(data=b64) + return ret diff --git a/unittests/_common.py b/unittests/_common.py index a0dc1fd3..684a27b1 100644 --- a/unittests/_common.py +++ b/unittests/_common.py @@ -41,13 +41,6 @@ def show_test_summary(pyfile): + os.path.basename(pyfile)) -def html_to_data_uri(html): - html = html.encode("utf-8", "replace") - b64 = base64.b64encode(html).decode("utf-8", "replace") - ret = "data:text/html;base64,{data}".format(data=b64) - return ret - - def run_message_loop(): # Run message loop for some time. # noinspection PyTypeChecker diff --git a/unittests/main_test.py b/unittests/main_test.py index 25405ce0..b0c2200c 100644 --- a/unittests/main_test.py +++ b/unittests/main_test.py @@ -112,7 +112,7 @@ """ -g_datauri = html_to_data_uri(g_datauri_data) +g_datauri = cef.GetDataUrl(g_datauri_data) class MainTest_IsolatedTest(unittest.TestCase): diff --git a/unittests/osr_test.py b/unittests/osr_test.py index a5a3753b..0e4191be 100644 --- a/unittests/osr_test.py +++ b/unittests/osr_test.py @@ -62,7 +62,7 @@ """ -g_datauri = html_to_data_uri(g_datauri_data) +g_datauri = cef.GetDataUrl(g_datauri_data) class OsrTest_IsolatedTest(unittest.TestCase):