diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bef11220 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +cef3-trunk +svn-win32-1.8.5 +cefpython.wiki +.tags* +/cython-version.* diff --git a/README.md b/README.md new file mode 100644 index 00000000..29751782 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# CEF Python + +Table of contents: + * [Introduction](#introduction) + * [Supported Python versions and platforms](#supported-python-versions-and-platforms) + * [Downloads](#downloads) + * [Help](#help) + * [Watch the project](#watch-the-project) + * [Support development](#support-development) + * [Thanks](#thanks) + +## Introduction + +CEF Python is an open source project founded by Czarek Tomczak in 2012 to provide python bindings for the Chromium Embedded Framework. See the growing list of applications using CEF on wikipedia. Examples of embedding CEF browser are available for many popular GUI toolkits including: wxPython, PyGTK, PyQt, PySide, Kivy, Panda3D and PyWin32. + +Some use cases for CEF: + +* Embed a web browser control with great HTML5 support (based on Chromium) +* Use it to create a HTML5 based GUI in an application. This can act as a replacement for GUI toolkits like wxWidgets/Qt/Gtk. For native communication between javascript and python use javascript bindings. Another option is to run an internal python web server and use websockets/XMLHttpRequest for js<>python communication. This way you can write a desktop app in the same way you write web apps. +* Render web content off-screen in applications that use custom drawing frameworks. See the Kivy and Panda3D examples. +* Use it for automated testing of existing web applications. Use it for web scraping, or as a web crawler or other kind of internet bots. + +## Supported Python versions and platforms + +* Supported Python versions: 2.7 (Python 3.4 will be supported soon, see [Issue #121](../../issues/121)) +* Supported platforms: Windows, Linux, Mac (both 32bit and 64bit binaries are available for all platforms) + +## Downloads + +* For Windows: see the Download_CEF3_Windows wiki page. +* For Linux: see the Download_CEF3_Linux wiki page. +* For Mac: see the Download_CEF3_Mac wiki page. + +## Help + +* Documentation is on the wiki pages. Start with the API page. +* Ask questions and report problems on the CEF Python Forum. +* Please do not use the [Issue Tracker](../../issues) for asking questions. +* Instructions on how to enable Flash Player are on the Plugins wiki page. +* Having problems with playing audio or video? See the AudioVideo wiki page. + +## Watch the project + +To be notified of updates watch the project on GitHub and additionally join the Forum and set membership settings to send Daily summaries via email. + +## Support development + + If you are interested in donating time to help with the CEF Python development please see the InternalDevelopment wiki page. If you would like to support general CEF Python development efforts by making a donation please click the Paypal "Donate" button to the right. At this time CEF Python is unable to accept donations that sponsor the development of specific features. If you are interested in sponsorship opportunities please contact Czarek directly. + +### Thanks + +* Thanks to the numerous individuals that made a Paypal donation: Walter Purvis, Rokas Stupuras, Alex Rattray, Greg Kacy, Paul Korzhyk. +* Thanks to those that have donated their time through code contributions: see the [AUTHORS.txt](../master/cefpython/AUTHORS.txt) file. Patches can be attached in the issue tracker. +* Many thanks to Cyan Inc. for sponsoring this project, making CEF Python 3 more mature. Lots of new features were added, including javascript bindings and Linux support. +* Thanks to Rentouch GmbH for sponsoring the development of the off-screen rendering support in CEF Python 3. +* Thanks to Thomas Wusatiuk for sponsoring the development of the web response reading features in CEF Python 3. +* Thanks to Adam Duston for donating a Macbook to aid the development of the Mac port. + +## Built a cool app? + +Built a cool app using CEF Python and would like to share info with the community? Talk about it on the CEF Python Forum. + +## Familiar with PHP or Go? + +The author of CEF Python is also working on CEF bindings for other languages such as PHP and Go. For PHP take a look at the [PHP Desktop](https://github.com/cztomczak/phpdesktop) project. For Go see the [CEF2go](https://github.com/cztomczak/cef2go) project on GitHub. diff --git a/cefpython/.gitignore b/cefpython/.gitignore new file mode 100644 index 00000000..af3ba3c4 --- /dev/null +++ b/cefpython/.gitignore @@ -0,0 +1,47 @@ +/cef1/windows/setup/build/ +*.pyc + +# If you want to ignore an already commited directory run: +# git rm --cached -r .idea + +/.idea/ +debug.log +error.log +console.log + +# WingIDE project files +/wingide.wpr +/wingide.wpu + +*.ncb +*.suo +*.user +*.aps +*.sdf +*.sln +Debug*/ +Release*/ +*.pdb + +ctags + +/cef1/windows/installer/Output/ +/cef3/windows/installer/Output/ + +# Inno setup files generated from a template +*.generated + +cython_debug/ + +cefpython_py27.pyd +cefpython_py32.pyd +cefpython_py27.so +cefpython_py32.so + +cython_includes/compile_time_constants.pxi + +debug_32bit/ +debug_64bit/ + +libcef_debug/ +libcef_release/ diff --git a/cefpython/AUTHORS.txt b/cefpython/AUTHORS.txt new file mode 100644 index 00000000..ac6d79e2 --- /dev/null +++ b/cefpython/AUTHORS.txt @@ -0,0 +1,17 @@ +Core developers: + + Czarek Tomczak + +Contributors (in order of first commit): + + 老农 cjjer + Richard Rodriguez + Roman Plášil + Rokas Stupuras + Greg Kacy + Thomas Dähling + Dominique Burnand + Greg Farrell + Finn Hughes + Marcelo Fernandez + Simon Hatt <9hatt2@@gmail.com> diff --git a/cefpython/LICENSE.txt b/cefpython/LICENSE.txt new file mode 100644 index 00000000..ba1b96ff --- /dev/null +++ b/cefpython/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright (c) 2012-2014 The CEF Python authors. All rights +reserved. Website: http://code.google.com/p/cefpython/ + +This product includes the following third party libraries: +* Chromium Embedded Framework licensed under the BSD 3-clause + license. Website: http://code.google.com/p/chromiumembedded/ + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/app.pyx b/cefpython/app.pyx new file mode 100644 index 00000000..ef1e8795 --- /dev/null +++ b/cefpython/app.pyx @@ -0,0 +1,14 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void App_OnBeforeCommandLineProcessing_BrowserProcess( + CefRefPtr[CefCommandLine] cefCommandLine + ) except * with gil: + global g_commandLineSwitches + try: + AppendSwitchesToCommandLine(cefCommandLine, g_commandLineSwitches) + Debug("App_OnBeforeCommandLineProcessing_BrowserProcess()") + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/browser.pyx b/cefpython/browser.pyx new file mode 100644 index 00000000..71631540 --- /dev/null +++ b/cefpython/browser.pyx @@ -0,0 +1,823 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +IF CEF_VERSION == 1: + # In CEF 1 there are both KT_KEYDOWN and KEYEVENT_KEYDOWN, and + # these are different constants, making a bit of confusion. + # In CEF 1 KT_ is for SendKeyEvent, KEYEVENT_ is for OnKeyEvent(). + # In CEF 3 there are only KEYEVENT_* constants. + KEYTYPE_KEYDOWN = cef_types.KT_KEYDOWN + KEYTYPE_KEYUP = cef_types.KT_KEYUP + KEYTYPE_CHAR = cef_types.KT_CHAR + +# Both CEF 1 and CEF 3. +# cef_mouse_button_type_t, SendMouseClickEvent(). +MOUSEBUTTON_LEFT = cef_types.MBT_LEFT +MOUSEBUTTON_MIDDLE = cef_types.MBT_MIDDLE +MOUSEBUTTON_RIGHT = cef_types.MBT_RIGHT + +# If you try to keep PyBrowser() objects inside cpp_vector you will +# get segmentation faults, as they will be garbage collected. + +cdef dict g_pyBrowsers = {} + +IF CEF_VERSION == 3: + # Unused function warning in CEF 1. + cdef PyBrowser GetPyBrowserById(int browserId): + if browserId in g_pyBrowsers: + return g_pyBrowsers[browserId] + return None + +cdef PyBrowser GetPyBrowser(CefRefPtr[CefBrowser] cefBrowser): + global g_pyBrowsers + if cefBrowser == NULL or not cefBrowser.get(): + Debug("GetPyBrowser(): returning None") + return None + + cdef PyBrowser pyBrowser + cdef int browserId + cdef int id + + browserId = cefBrowser.get().GetIdentifier() + if browserId in g_pyBrowsers: + return g_pyBrowsers[browserId] + + for id, pyBrowser in g_pyBrowsers.items(): + if not pyBrowser.cefBrowser.get(): + Debug("GetPyBrowser(): removing an empty CefBrowser reference, " + "browserId=%s" % id) + del g_pyBrowsers[id] + + Debug("GetPyBrowser(): creating new PyBrowser, browserId=%s" % browserId) + pyBrowser = PyBrowser() + pyBrowser.cefBrowser = cefBrowser + g_pyBrowsers[browserId] = pyBrowser + + # Inherit client callbacks and javascript bindings + # from parent browser. + + # Checking __outerWindowHandle as we should not inherit + # client callbacks and javascript bindings if the browser + # was created explicitily by calling CreateBrowserSync(). + + # Popups inherit client callbacks by default. + + # Popups inherit javascript bindings only when "bindToPopups" + # constructor param was set to True. + + cdef WindowHandle openerHandle + cdef dict clientCallbacks + cdef JavascriptBindings javascriptBindings + cdef PyBrowser tempPyBrowser + + if pyBrowser.IsPopup() and \ + not pyBrowser.GetUserData("__outerWindowHandle"): + openerHandle = pyBrowser.GetOpenerWindowHandle() + for id, tempPyBrowser in g_pyBrowsers.items(): + if tempPyBrowser.GetWindowHandle() == openerHandle: + clientCallbacks = tempPyBrowser.GetClientCallbacksDict() + if clientCallbacks: + pyBrowser.SetClientCallbacksDict(clientCallbacks) + javascriptBindings = tempPyBrowser.GetJavascriptBindings() + if javascriptBindings: + if javascriptBindings.GetBindToPopups(): + pyBrowser.SetJavascriptBindings(javascriptBindings) + return pyBrowser + +IF CEF_VERSION == 3: + # Unused function warning in CEF 1. + cdef void RemovePyBrowser(int browserId) except *: + # Called from LifespanHandler_OnBeforeClose(). + # TODO: call this function also in CEF 1. + global g_pyBrowsers + if browserId in g_pyBrowsers: + if len(g_pyBrowsers) == 1: + # This is the last browser remaining. + if g_sharedRequestContext.get(): + # A similar release is done in Shutdown and CloseBrowser. + Debug("RemovePyBrowser: releasing shared request context") + g_sharedRequestContext.Assign(NULL) + Debug("del g_pyBrowsers[%s]" % browserId) + del g_pyBrowsers[browserId] + else: + Debug("RemovePyBrowser() FAILED: browser not found, id = %s" \ + % browserId) + +cpdef PyBrowser GetBrowserByWindowHandle(WindowHandle windowHandle): + cdef PyBrowser pyBrowser + for browserId in g_pyBrowsers: + pyBrowser = g_pyBrowsers[browserId] + if (pyBrowser.GetWindowHandle() == windowHandle or + pyBrowser.GetUserData("__outerWindowHandle") == long(windowHandle)): + return pyBrowser + return None + +cdef public void PyBrowser_ShowDevTools(CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + # Called from ClientHandler::OnContextMenuCommand + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyBrowser.ShowDevTools() + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +# ----------------------------------------------------------------------------- + +cdef class PyBrowser: + cdef CefRefPtr[CefBrowser] cefBrowser + + cdef public dict clientCallbacks + cdef public list allowedClientCallbacks + cdef public JavascriptBindings javascriptBindings + cdef public dict userData + + # Properties used by ToggleFullscreen(). + cdef public int isFullscreen + cdef public int maximized + cdef public int gwlStyle + cdef public int gwlExStyle + cdef public tuple windowRect + + # C-level attributes are initialized to 0 automatically. + cdef void* imageBuffer + + cdef CefRefPtr[CefBrowser] GetCefBrowser(self) except *: + if self.cefBrowser != NULL and self.cefBrowser.get(): + return self.cefBrowser + raise Exception("PyBrowser.GetCefBrowser() failed: CefBrowser " + "was destroyed") + + IF CEF_VERSION == 3: + + cdef CefRefPtr[CefBrowserHost] GetCefBrowserHost(self) except *: + cdef CefRefPtr[CefBrowserHost] cefBrowserHost = ( + self.GetCefBrowser().get().GetHost()) + if cefBrowserHost != NULL and cefBrowserHost.get(): + return cefBrowserHost + raise Exception("PyBrowser.GetCefBrowserHost() failed: this " + "method can only be called in the browser " + "process.") + + def __init__(self): + self.clientCallbacks = {} + self.allowedClientCallbacks = [] + self.userData = {} + + def __dealloc__(self): + if self.imageBuffer: + free(self.imageBuffer) + + cpdef py_void SetClientCallback(self, py_string name, object callback): + IF CEF_VERSION == 1: + self.SetClientCallback_CEF1(name, callback) + ELIF CEF_VERSION == 3: + self.SetClientCallback_CEF3(name, callback) + + # ------------------------------------------------------------------------- + # CEF 1 + # ------------------------------------------------------------------------- + cpdef py_void SetClientCallback_CEF1(self, + py_string name, object callback): + if not self.allowedClientCallbacks: + # CefLoadHandler. + self.allowedClientCallbacks += ["OnLoadEnd", "OnLoadError", + "OnLoadStart"] + # CefKeyboardHandler. + self.allowedClientCallbacks += ["OnKeyEvent"] + # CefV8ContextHandler. + self.allowedClientCallbacks += ["OnContextCreated", + "OnContextReleased" ,"OnUncaughtException"] + # CefRequestHandler. + self.allowedClientCallbacks += ["OnBeforeBrowse", + "OnBeforeResourceLoad", "OnResourceRedirect", + "OnResourceResponse", "OnProtocolExecution", + "GetDownloadHandler", "GetAuthCredentials", + "GetCookieManager"] + + # CefDisplayHandler. + self.allowedClientCallbacks += ["OnAddressChange", + "OnConsoleMessage", "OnContentsSizeChange", + "OnNavStateChange", "OnStatusMessage", "OnTitleChange", + "OnTooltip"] + # LifespanHandler. + self.allowedClientCallbacks += ["DoClose", "OnAfterCreated", + "OnBeforeClose", "RunModal"] + # RenderHandler + self.allowedClientCallbacks += ["GetViewRect", "GetScreenRect", + "GetScreenPoint", "OnPopupShow", "OnPopupSize", + "OnPaint", "OnCursorChange"] + # DragHandler + self.allowedClientCallbacks += ["OnDragStart", "OnDragEnter"] + if name not in self.allowedClientCallbacks: + raise Exception("Browser.SetClientCallback() failed: unknown " + "callback: %s" % name) + self.clientCallbacks[name] = callback + + # ------------------------------------------------------------------------- + # CEF 3 + # ------------------------------------------------------------------------- + cpdef py_void SetClientCallback_CEF3(self, + py_string name, object callback): + if not self.allowedClientCallbacks: + # DisplayHandler + self.allowedClientCallbacks += [ + "OnAddressChange", "OnTitleChange", "OnTooltip", + "OnStatusMessage", "OnConsoleMessage"] + # KeyboardHandler + self.allowedClientCallbacks += ["OnPreKeyEvent", "OnKeyEvent"]; + # RequestHandler + # NOTE: OnCertificateError and OnBeforePluginLoad are not + # included as they must be set using + # cefpython.SetGlobalClientCallback(). + self.allowedClientCallbacks += ["OnBeforeResourceLoad", + "OnResourceRedirect", "GetAuthCredentials", + "OnQuotaRequest", "OnProtocolExecution", + "GetResourceHandler", + "OnBeforeBrowse", "OnRendererProcessTerminated", + "OnPluginCrashed"] + # RequestContextHandler + self.allowedClientCallbacks += ["GetCookieManager"] + # LoadHandler + self.allowedClientCallbacks += ["OnLoadingStateChange", + "OnLoadStart", "OnLoadEnd", "OnLoadError"] + # LifespanHandler + # NOTE: OnAfterCreated not included as it must be set using + # cefpython.SetGlobalClientCallback(). + self.allowedClientCallbacks += ["OnBeforePopup", + "RunModal", "DoClose", "OnBeforeClose"] + # RenderHandler + self.allowedClientCallbacks += ["GetRootScreenRect", + "GetViewRect", "GetScreenPoint", "GetScreenInfo", + "OnPopupShow", "OnPopupSize", "OnPaint", "OnCursorChange", + "OnScrollOffsetChanged"] + # JavascriptDialogHandler + self.allowedClientCallbacks += ["OnJavascriptDialog", + "OnBeforeUnloadJavascriptDialog", + "OnResetJavascriptDialogState", + "OnJavascriptDialogClosed"] + + if name not in self.allowedClientCallbacks: + raise Exception("Browser.SetClientCallback() failed: unknown " + "callback: %s" % name) + self.clientCallbacks[name] = callback + + cpdef py_void SetClientHandler(self, object clientHandler): + if not hasattr(clientHandler, "__class__"): + raise Exception("Browser.SetClientHandler() failed: __class__ " + "attribute missing") + cdef dict methods = {} + cdef py_string key + cdef object method + cdef tuple value + for value in inspect.getmembers(clientHandler, + predicate=inspect.ismethod): + key = value[0] + method = value[1] + if key and key[0] != '_': + self.SetClientCallback(key, method) + + cpdef object GetClientCallback(self, py_string name): + if name in self.clientCallbacks: + return self.clientCallbacks[name] + + cpdef py_void SetClientCallbacksDict(self, dict clientCallbacks): + self.clientCallbacks = clientCallbacks + + cpdef dict GetClientCallbacksDict(self): + return self.clientCallbacks + + cpdef py_void SetJavascriptBindings(self, JavascriptBindings bindings): + self.javascriptBindings = bindings + IF CEF_VERSION == 1: + if self.GetUserData("__v8ContextCreated"): + Debug("Browser.SetJavascriptBindings(): v8 context already" + "created, calling Rebind()") + self.javascriptBindings.Rebind() + ELIF CEF_VERSION == 3: + self.javascriptBindings.Rebind() + + cpdef JavascriptBindings GetJavascriptBindings(self): + return self.javascriptBindings + + # -------------- + # CEF API. + # -------------- + + cpdef py_bool CanGoBack(self): + return self.GetCefBrowser().get().CanGoBack() + + cpdef py_bool CanGoForward(self): + return self.GetCefBrowser().get().CanGoForward() + + IF CEF_VERSION == 1: + + cpdef object ClearHistory(self): + self.GetCefBrowser().get().ClearHistory() + + cpdef py_void ParentWindowWillClose(self): + IF CEF_VERSION == 1: + self.GetCefBrowser().get().ParentWindowWillClose() + ELIF CEF_VERSION == 3: + self.GetCefBrowserHost().get().ParentWindowWillClose() + + cpdef py_void CloseBrowser(self, py_bool forceClose=False): + IF CEF_VERSION == 1: + Debug("CefBrowser::CloseBrowser(%s)" % forceClose) + self.GetCefBrowser().get().CloseBrowser(bool(forceClose)) + ELIF CEF_VERSION == 3: + # ParentWindowWillClose() should be called by user when + # implementing LifespanHandler::DoClose(). + # | Debug("CefBrowser::ParentWindowWillClose()") + # | self.GetCefBrowserHost().get().ParentWindowWillClose() + if len(g_pyBrowsers) == 1: + # This is the last browser remaining. + if g_sharedRequestContext.get(): + # A similar release is done in Shutdown + # and RemovePyBrowser. + Debug("CloseBrowser: releasing shared request context") + g_sharedRequestContext.Assign(NULL) + Debug("CefBrowser::CloseBrowser(%s)" % forceClose) + self.GetCefBrowserHost().get().CloseBrowser(bool(forceClose)) + + IF CEF_VERSION == 1: + + cpdef py_void CloseDevTools(self): + self.GetCefBrowser().get().CloseDevTools() + + def ExecuteFunction(self, *args): + self.GetMainFrame().ExecuteFunction(*args) + + cpdef py_void ExecuteJavascript(self, py_string jsCode, + py_string scriptUrl="", int startLine=0): + self.GetMainFrame().ExecuteJavascript(jsCode, scriptUrl, startLine) + + cpdef py_void Find(self, int searchId, py_string searchText, + py_bool forward, py_bool matchCase, + py_bool findNext): + cdef CefString cefSearchText + PyToCefString(searchText, cefSearchText) + IF CEF_VERSION == 3: + self.GetCefBrowserHost().get().Find(searchId, cefSearchText, + bool(forward), bool(matchCase), bool(findNext)) + ELIF CEF_VERSION == 1: + self.GetCefBrowser().get().Find(searchId, cefSearchText, + bool(forward), bool(matchCase), bool(findNext)) + + cpdef PyFrame GetFocusedFrame(self): + assert IsThread(TID_UI), ( + "Browser.GetFocusedFrame() may only be called on UI thread") + return GetPyFrame(self.GetCefBrowser().get().GetFocusedFrame()) + + cpdef PyFrame GetFrame(self, py_string name): + assert IsThread(TID_UI), ( + "Browser.GetFrame() may only be called on the UI thread") + cdef CefString cefName + PyToCefString(name, cefName) + return GetPyFrame(self.GetCefBrowser().get().GetFrame(cefName)) + + IF CEF_VERSION == 3: + cpdef object GetFrameByIdentifier(self, object identifier): + return GetPyFrame(self.GetCefBrowser().get().GetFrame( + long(identifier))) + + cpdef list GetFrameNames(self): + assert IsThread(TID_UI), ( + "Browser.GetFrameNames() may only be called on the UI thread") + cdef cpp_vector[CefString] cefNames + self.GetCefBrowser().get().GetFrameNames(cefNames) + cdef list names = [] + cdef cpp_vector[CefString].iterator iterator = cefNames.begin() + cdef CefString cefString + while iterator != cefNames.end(): + cefString = deref(iterator) + names.append(CefToPyString(cefString)) + preinc(iterator) + return names + + cpdef list GetFrames(self): + cdef list names = self.GetFrameNames() + cdef PyFrame frame + cdef list frames = [] + for name in names: + frame = self.GetFrame(name) + frames.append(frame) + return frames + + cpdef int GetIdentifier(self) except *: + return self.GetCefBrowser().get().GetIdentifier() + + cpdef PyFrame GetMainFrame(self): + return GetPyFrame(self.GetCefBrowser().get().GetMainFrame()) + + cpdef WindowHandle GetOpenerWindowHandle(self) except *: + cdef WindowHandle hwnd + IF CEF_VERSION == 1: + hwnd = self.GetCefBrowser().get().GetOpenerWindowHandle() + ELIF CEF_VERSION == 3: + hwnd = self.GetCefBrowserHost().get().GetOpenerWindowHandle() + return hwnd + + cpdef WindowHandle GetOuterWindowHandle(self) except *: + if self.GetUserData("__outerWindowHandle"): + return self.GetUserData("__outerWindowHandle") + else: + return self.GetWindowHandle() + + cpdef py_string GetUrl(self): + return self.GetMainFrame().GetUrl() + + cpdef object GetUserData(self, object key): + if key in self.userData: + return self.userData[key] + return None + + cpdef WindowHandle GetWindowHandle(self) except *: + cdef WindowHandle hwnd + IF CEF_VERSION == 1: + hwnd = self.GetCefBrowser().get().GetWindowHandle() + ELIF CEF_VERSION == 3: + hwnd = self.GetCefBrowserHost().get().GetWindowHandle() + return hwnd + + cpdef double GetZoomLevel(self) except *: + IF CEF_VERSION == 1: + assert IsThread(TID_UI), ( + "Browser.GetZoomLevel() may only be called on UI thread") + cdef double zoomLevel + IF CEF_VERSION == 1: + zoomLevel = self.GetCefBrowser().get().GetZoomLevel() + ELIF CEF_VERSION == 3: + zoomLevel = self.GetCefBrowserHost().get().GetZoomLevel() + return zoomLevel + + cpdef py_void GoBack(self): + self.GetCefBrowser().get().GoBack() + + cpdef py_void GoForward(self): + self.GetCefBrowser().get().GoForward() + + cpdef py_bool HasDocument(self): + return self.GetCefBrowser().get().HasDocument() + + IF CEF_VERSION == 1: + cpdef py_void HidePopup(self): + self.GetCefBrowser().get().HidePopup() + + cpdef py_bool IsFullscreen(self): + return bool(self.isFullscreen) + + cpdef py_bool IsPopup(self): + return self.GetCefBrowser().get().IsPopup() + + IF CEF_VERSION == 1: + cpdef py_bool IsPopupVisible(self): + assert IsThread(TID_UI), ( + "Browser.IsPopupVisible() may only be called on UI thread") + return self.GetCefBrowser().get().IsPopupVisible() + + cpdef py_bool IsWindowRenderingDisabled(self): + IF CEF_VERSION == 1: + return self.GetCefBrowser().get().IsWindowRenderingDisabled() + ELIF CEF_VERSION == 3: + return self.GetCefBrowserHost().get().IsWindowRenderingDisabled() + + cpdef py_string LoadUrl(self, py_string url): + self.GetMainFrame().LoadUrl(url) + + cpdef py_void Navigate(self, py_string url): + self.LoadUrl(url) + + IF CEF_VERSION == 3: + cpdef py_void Print(self): + self.GetCefBrowserHost().get().Print() + + cpdef py_void Reload(self): + self.GetCefBrowser().get().Reload() + + cpdef py_void ReloadIgnoreCache(self): + self.GetCefBrowser().get().ReloadIgnoreCache() + + cpdef py_void SetFocus(self, enable): + IF CEF_VERSION == 1: + self.GetCefBrowser().get().SetFocus(bool(enable)) + ELIF CEF_VERSION == 3: + self.GetCefBrowserHost().get().SetFocus(bool(enable)) + + cpdef py_void SetUserData(self, object key, object value): + self.userData[key] = value + + cpdef py_void SetZoomLevel(self, double zoomLevel): + IF CEF_VERSION == 1: + self.GetCefBrowser().get().SetZoomLevel(zoomLevel) + ELIF CEF_VERSION == 3: + self.GetCefBrowserHost().get().SetZoomLevel(zoomLevel) + + cpdef py_void ShowDevTools(self): + cdef CefString cefUrl = self.GetCefBrowserHost().get().GetDevToolsURL(\ + True) + cdef py_string url = CefToPyString(cefUrl) + # Example url returned: + # | http://localhost:54008/devtools/devtools.html?ws=localhost:54008 + # | /devtools/page/1538ed984a2a4a90e5ed941c7d142a12 + # Let's replace "localhost" with "127.0.0.1", using the ip address + # which is more reliable. + url = url.replace("localhost:", "127.0.0.1:") + jsCode = ("window.open('%s');" % url) + self.GetMainFrame().ExecuteJavascript(jsCode) + + cpdef py_void StopLoad(self): + self.GetCefBrowser().get().StopLoad() + + cpdef py_void StopFinding(self, py_bool clearSelection): + IF CEF_VERSION == 3: + self.GetCefBrowserHost().get().StopFinding(bool(clearSelection)) + ELIF CEF_VERSION == 1: + self.GetCefBrowser().get().StopFinding(bool(clearSelection)) + + cpdef py_void ToggleFullscreen(self): + IF UNAME_SYSNAME == "Windows": + self.ToggleFullscreen_Windows() + + IF UNAME_SYSNAME == "Windows": + + cpdef py_void ToggleFullscreen_Windows(self): + cdef WindowHandle windowHandle + if self.GetUserData("__outerWindowHandle"): + windowHandle = self.GetUserData("__outerWindowHandle") + else: + windowHandle = self.GetWindowHandle() + + # Offscreen browser will have an empty window handle. + assert windowHandle, ( + "Browser.ToggleFullscreen() failed: no window handle " + "found") + + cdef HWND hwnd = int(windowHandle) + cdef RECT rect + cdef HMONITOR monitor + cdef MONITORINFO monitorInfo + monitorInfo.cbSize = sizeof(monitorInfo) + + # Logic copied from chromium > fullscreen_handler.cc > + # FullscreenHandler::SetFullscreenImpl: + # http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/ + # fullscreen_handler.cc + + cdef py_bool for_metro = False + + if not self.isFullscreen: + self.maximized = IsZoomed(hwnd) + if self.maximized: + SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0) + self.gwlStyle = GetWindowLong(hwnd, GWL_STYLE) + self.gwlExStyle = GetWindowLong(hwnd, GWL_EXSTYLE) + GetWindowRect(hwnd, &rect) + self.windowRect = (rect.left, rect.top, + rect.right, rect.bottom) + + cdef int removeStyle, removeExStyle + cdef int left, top, right, bottom + + if not self.isFullscreen: + removeStyle = WS_CAPTION | WS_THICKFRAME + removeExStyle = (WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE + | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE) + SetWindowLong(hwnd, GWL_STYLE, + self.gwlStyle & ~(removeStyle)) + SetWindowLong(hwnd, GWL_EXSTYLE, + self.gwlExStyle & ~(removeExStyle)) + + if not for_metro: + # MONITOR_DEFAULTTONULL, MONITOR_DEFAULTTOPRIMARY, + # MONITOR_DEFAULTTONEAREST + monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) + GetMonitorInfo(monitor, &monitorInfo) + left = monitorInfo.rcMonitor.left + top = monitorInfo.rcMonitor.top + right = monitorInfo.rcMonitor.right + bottom = monitorInfo.rcMonitor.bottom + SetWindowPos(hwnd, NULL, + left, top, right-left, bottom-top, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED) + else: + SetWindowLong(hwnd, GWL_STYLE, int(self.gwlStyle)) + SetWindowLong(hwnd, GWL_EXSTYLE, int(self.gwlExStyle)) + + if not for_metro: + (left, top, right, bottom) = self.windowRect + SetWindowPos(hwnd, NULL, + int(left), int(top), + int(right-left), int(bottom-top), + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED) + + if self.maximized: + SendMessage(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0) + + self.isFullscreen = int(not bool(self.isFullscreen)) + + # Off-screen rendering. + + IF CEF_VERSION == 1: + + cpdef tuple GetSize(self, PaintElementType paintElementType): + assert IsThread(TID_UI), ( + "Browser.GetSize(): this method should only be called " + "on the UI thread") + cdef int width = 0 + cdef int height = 0 + cdef cpp_bool ret = self.GetCefBrowser().get().GetSize( + paintElementType, width, height) + if ret: + return (width, height) + else: + return (0, 0) + + cpdef py_void SetSize(self, PaintElementType paintElementType, + int width, int height): + self.GetCefBrowser().get().SetSize(paintElementType, width, height) + + cpdef py_void Invalidate(self, list dirtyRect): + assert len(dirtyRect) == 4, ( + "Browser.Invalidate() failed, dirtyRect is invalid") + cdef CefRect cefRect = CefRect( + dirtyRect[0], dirtyRect[1], dirtyRect[2], dirtyRect[3]) + self.GetCefBrowser().get().Invalidate(cefRect) + + IF CEF_VERSION == 1 and UNAME_SYSNAME == "Windows": + cpdef PaintBuffer GetImage(self, PaintElementType paintElementType, + int width, int height): + assert IsThread(TID_UI), ( + "Browser.GetImage(): this method should only be called " + "on the UI thread") + + IF UNAME_SYSNAME == "Windows": + return self.GetImage_Windows(paintElementType, width, height) + ELSE: + return None + + cdef PaintBuffer GetImage_Windows(self, + PaintElementType paintElementType, int width, int height): + if not self.imageBuffer: + self.imageBuffer = malloc(width*height*4) + cdef cpp_bool ret = self.GetCefBrowser().get().GetImage( + paintElementType, width, height, self.imageBuffer) + cdef PaintBuffer paintBuffer + if ret: + paintBuffer = CreatePaintBuffer( + self.imageBuffer, width, height) + return paintBuffer + else: + return None + + # Sending mouse/key events. + IF CEF_VERSION == 1: + cpdef py_void SendKeyEvent(self, cef_types.cef_key_type_t keyType, + tuple keyInfo, int modifiers): + cdef CefKeyInfo cefKeyInfo + IF UNAME_SYSNAME == "Windows": + assert len(keyInfo) == 3, "Invalid keyInfo param" + cefKeyInfo.key = keyInfo[0] + cefKeyInfo.sysChar = keyInfo[1] + cefKeyInfo.imeChar = keyInfo[2] + ELIF UNAME_SYSNAME == "Darwin": + cefKeyInfo.keyCode = keyInfo[0] + cefKeyInfo.character = keyInfo[1] + cefKeyInfo.characterNoModifiers = keyInfo[2] + ELIF UNAME_SYSNAME == "Linux": + cefKeyInfo.key = keyInfo[0] + ELSE: + raise Exception("Invalid UNAME_SYSNAME") + + self.GetCefBrowser().get().SendKeyEvent(keyType, cefKeyInfo, + modifiers) + + cpdef py_void SendMouseClickEvent(self, int x, int y, + cef_types.cef_mouse_button_type_t mouseButtonType, + py_bool mouseUp, int clickCount, int modifiers=0): + self.GetCefBrowser().get().SendMouseClickEvent(x, y, + mouseButtonType, bool(mouseUp), clickCount) + + cpdef py_void SendMouseMoveEvent(self, int x, int y, + py_bool mouseLeave, int modifiers=0): + self.GetCefBrowser().get().SendMouseMoveEvent(x, y, + bool(mouseLeave)) + + cpdef py_void SendMouseWheelEvent(self, int x, int y, + int deltaX, int deltaY, int modifiers=0): + self.GetCefBrowser().get().SendMouseWheelEvent(x, y, + deltaX, deltaY) + + cpdef py_void SendFocusEvent(self, py_bool setFocus): + self.GetCefBrowser().get().SendFocusEvent(bool(setFocus)) + + cpdef py_void SendCaptureLostEvent(self): + self.GetCefBrowser().get().SendCaptureLostEvent() + + ELIF CEF_VERSION == 3: + cpdef py_void SendKeyEvent(self, dict pyEvent): + cdef CefKeyEvent cefEvent + if "type" in pyEvent: + cefEvent.type = int(pyEvent["type"]) + if "modifiers" in pyEvent: + cefEvent.modifiers = long(pyEvent["modifiers"]) + if ("windows_key_code" in pyEvent) and UNAME_SYSNAME == "Windows": + cefEvent.windows_key_code = int(pyEvent["windows_key_code"]) + if "native_key_code" in pyEvent: + cefEvent.native_key_code = int(pyEvent["native_key_code"]) + if "is_system_key" in pyEvent: + cefEvent.is_system_key = bool(pyEvent["is_system_key"]) + if "character" in pyEvent: + cefEvent.character = int(pyEvent["character"]) + if "unmodified_character" in pyEvent: + cefEvent.unmodified_character = \ + int(pyEvent["unmodified_character"]) + if "focus_on_editable_field" in pyEvent: + cefEvent.focus_on_editable_field = \ + bool(pyEvent["focus_on_editable_field"]) + self.GetCefBrowserHost().get().SendKeyEvent(cefEvent) + + cpdef py_void SendMouseClickEvent(self, int x, int y, + cef_types.cef_mouse_button_type_t mouseButtonType, + py_bool mouseUp, int clickCount, int modifiers=0): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + mouseEvent.modifiers = modifiers + self.GetCefBrowserHost().get().SendMouseClickEvent(mouseEvent, + mouseButtonType, bool(mouseUp), clickCount) + + cpdef py_void SendMouseMoveEvent(self, int x, int y, + py_bool mouseLeave, int modifiers=0): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + mouseEvent.modifiers = modifiers + self.GetCefBrowserHost().get().SendMouseMoveEvent(mouseEvent, + bool(mouseLeave)) + + cpdef py_void SendMouseWheelEvent(self, int x, int y, + int deltaX, int deltaY, int modifiers=0): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + mouseEvent.modifiers = modifiers + self.GetCefBrowserHost().get().SendMouseWheelEvent(mouseEvent, + deltaX, deltaY) + + cpdef py_void SendFocusEvent(self, py_bool setFocus): + self.GetCefBrowserHost().get().SendFocusEvent(bool(setFocus)) + + cpdef py_void SendCaptureLostEvent(self): + self.GetCefBrowserHost().get().SendCaptureLostEvent() + # ENDIF CEF_VERSION == 3 / Sending mouse/key events. + + IF CEF_VERSION == 3: + cpdef py_void StartDownload(self, py_string url): + self.GetCefBrowserHost().get().StartDownload(PyToCefStringValue( + url)) + + cpdef py_void SetMouseCursorChangeDisabled(self, py_bool disabled): + self.GetCefBrowserHost().get().SetMouseCursorChangeDisabled( + bool(disabled)) + + cpdef py_bool IsMouseCursorChangeDisabled(self): + return self.GetCefBrowserHost().get().IsMouseCursorChangeDisabled() + + cpdef py_void WasResized(self): + self.GetCefBrowserHost().get().WasResized() + + cpdef py_void WasHidden(self, py_bool hidden): + self.GetCefBrowserHost().get().WasHidden(bool(hidden)) + + cpdef py_void NotifyScreenInfoChanged(self): + self.GetCefBrowserHost().get().NotifyScreenInfoChanged() + + # virtual CefTextInputContext GetNSTextInputContext() =0; + # virtual void HandleKeyEventBeforeTextInputClient(CefEventHandle keyEvent) =0; + # virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0; + + cdef void SendProcessMessage(self, cef_process_id_t targetProcess, + object frameId, py_string messageName, list pyArguments + ) except *: + cdef CefRefPtr[CefProcessMessage] message = \ + CefProcessMessage_Create(PyToCefStringValue(messageName)) + # This does not work, no idea why, the CEF implementation + # seems not to allow it, both Assign() and swap() do not work: + # | message.get().GetArgumentList().Assign(arguments.get()) + # | message.get().GetArgumentList().swap(arguments) + cdef CefRefPtr[CefListValue] messageArguments = \ + message.get().GetArgumentList() + PyListToExistingCefListValue(self.GetIdentifier(), frameId, + pyArguments, messageArguments) + Debug("SendProcessMessage(): message=%s, arguments size=%d" % ( + messageName, + message.get().GetArgumentList().get().GetSize())) + cdef cpp_bool success = \ + self.GetCefBrowser().get().SendProcessMessage( + targetProcess, message) + if not success: + raise Exception("Browser.SendProcessMessage() failed: "\ + "messageName=%s" % messageName) diff --git a/cefpython/browser_process_handler_cef3.pyx b/cefpython/browser_process_handler_cef3.pyx new file mode 100644 index 00000000..e3f38639 --- /dev/null +++ b/cefpython/browser_process_handler_cef3.pyx @@ -0,0 +1,24 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void BrowserProcessHandler_OnRenderProcessThreadCreated( + CefRefPtr[CefListValue] extra_info + ) except * with gil: + try: + # Keys 0 and 1 are already set in C++ code - to pass debug options. + pass + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void BrowserProcessHandler_OnBeforeChildProcessLaunch( + CefRefPtr[CefCommandLine] cefCommandLine + ) except * with gil: + global g_commandLineSwitches + try: + AppendSwitchesToCommandLine(cefCommandLine, g_commandLineSwitches) + Debug("BrowserProcessHandler_OnBeforeChildProcessLaunch()") + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/callback_cef3.pyx b/cefpython/callback_cef3.pyx new file mode 100644 index 00000000..104cd732 --- /dev/null +++ b/cefpython/callback_cef3.pyx @@ -0,0 +1,18 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PyCallback CreatePyCallback( + CefRefPtr[CefCallback] cefCallback): + cdef PyCallback pyCallback = PyCallback() + pyCallback.cefCallback = cefCallback + return pyCallback + +cdef class PyCallback: + cdef CefRefPtr[CefCallback] cefCallback + + cpdef py_void Continue(self): + self.cefCallback.get().Continue() + + cpdef py_void Cancel(self): + self.cefCallback.get().Cancel() diff --git a/cefpython/cef1/BUILD_COMPATIBILITY.txt b/cefpython/cef1/BUILD_COMPATIBILITY.txt new file mode 100644 index 00000000..edc159a6 --- /dev/null +++ b/cefpython/cef1/BUILD_COMPATIBILITY.txt @@ -0,0 +1,16 @@ +Chromium/CEF branch: + 1453 +Chromium release url: + http://src.chromium.org/svn/releases/27.0.1453.110 +CEF revision: + 1273 +CEF repository url: + http://chromiumembedded.googlecode.com/svn/branches/1453/cef1@1273 + +---- + +To convert chromium revision back to version string use this url: +http://src.chromium.org/viewvc/chrome/branches/xxxx/src/chrome/VERSION?revision=xxxx + +The latest chromium version in given branch: +http://src.chromium.org/viewvc/chrome/branches/xxxx/src/chrome/VERSION diff --git a/cefpython/cef1/cefpython_public_api.h b/cefpython/cef1/cefpython_public_api.h new file mode 100644 index 00000000..f55df41f --- /dev/null +++ b/cefpython/cef1/cefpython_public_api.h @@ -0,0 +1,30 @@ +// d:\cefpython\src\setup/cefpython.h(22) : warning C4190: 'RequestHandler_GetCookieManager' +// has C-linkage specified, but returns UDT 'CefRefPtr' which is incompatible with C +#if defined(OS_WIN) +#pragma warning(disable:4190) +#endif + +// All the imports that are required when including "cefpython.h". +#include "include/cef_client.h" +#include "include/cef_web_urlrequest.h" +#include "include/cef_cookie.h" +#include "util.h" + +// To be able to use 'public' declarations you need to include Python.h and cefpython.h. +#include "Python.h" + +// Python 3.2 fix - DL_IMPORT is not defined in Python.h +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +#if defined(OS_WIN) +#include "windows/setup/cefpython.h" +#endif + +#if defined(OS_LINUX) +#include "linux/setup/cefpython.h" +#endif diff --git a/cefpython/cef1/client_handler/.gitignore b/cefpython/cef1/client_handler/.gitignore new file mode 100644 index 00000000..151a620f --- /dev/null +++ b/cefpython/cef1/client_handler/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a \ No newline at end of file diff --git a/cefpython/cef1/client_handler/Makefile b/cefpython/cef1/client_handler/Makefile new file mode 100644 index 00000000..9baf4a88 --- /dev/null +++ b/cefpython/cef1/client_handler/Makefile @@ -0,0 +1,20 @@ +# -g - extra debug information +# -O1 - more precise backtraces +# -fPIC - required when using -shared option +# -Wall - show important warnings +# -Werror - treat warnings as errors + +CC = g++ +CCFLAGS = -g + +SRC = client_handler.cpp web_request_client.cpp content_filter_handler.cpp cookie_visitor.cpp download_handler.cpp +OBJ = $(SRC:.cpp=.o) +OUT = libclient_handler.a + +INC = -I./../ -I/usr/include/python2.7 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include + +.cpp.o: + $(CC) -fPIC $(INC) $(CCFLAGS) -c $< -o $@ + +$(OUT): $(OBJ) + ar rcs $(OUT) $(OBJ) diff --git a/cefpython/cef1/client_handler/client_handler.cpp b/cefpython/cef1/client_handler/client_handler.cpp new file mode 100644 index 00000000..b2884fcc --- /dev/null +++ b/cefpython/cef1/client_handler/client_handler.cpp @@ -0,0 +1,347 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "client_handler.h" +#include + +// The const_cast<> were required in Cython <= 0.17.4, +// TODO: get rid of it. + +// ----------------------------------------------------------------------------- +// CefLoadHandler +// ----------------------------------------------------------------------------- + +void ClientHandler::OnLoadEnd( + CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadEnd(browser, frame, httpStatusCode); +} + +void ClientHandler::OnLoadStart( + CefRefPtr browser, + CefRefPtr frame) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadStart(browser, frame); +} + +bool ClientHandler::OnLoadError( + CefRefPtr browser, + CefRefPtr frame, + cef_handler_errorcode_t errorCode, + const CefString& failedUrl, + CefString& errorText + ) { + REQUIRE_UI_THREAD(); + return LoadHandler_OnLoadError( + browser, frame, errorCode, const_cast(failedUrl), errorText); +} + +// ----------------------------------------------------------------------------- +// CefKeyboardHandler +// ----------------------------------------------------------------------------- + +bool ClientHandler::OnKeyEvent( + CefRefPtr browser, + cef_handler_keyevent_type_t eventType, + int keyCode, + int modifiers, + bool isSystemKey, + bool isAfterJavascript) { + REQUIRE_UI_THREAD(); + return KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript); +} + +// ----------------------------------------------------------------------------- +// CefV8ContextHandler +// ----------------------------------------------------------------------------- + +void ClientHandler::OnContextCreated( + CefRefPtr cefBrowser, + CefRefPtr cefFrame, + CefRefPtr v8Context) { + REQUIRE_UI_THREAD(); + V8ContextHandler_OnContextCreated(cefBrowser, cefFrame, v8Context); +} + +void ClientHandler::OnContextReleased( + CefRefPtr cefBrowser, + CefRefPtr cefFrame, + CefRefPtr v8Context) { + REQUIRE_UI_THREAD(); + V8ContextHandler_OnContextReleased(cefBrowser, cefFrame, v8Context); +} + +void ClientHandler::OnUncaughtException( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) { + REQUIRE_UI_THREAD(); + V8ContextHandler_OnUncaughtException( + browser, frame, context, exception, stackTrace); +} + +// ----------------------------------------------------------------------------- +// CefRequestHandler +// ----------------------------------------------------------------------------- + +bool ClientHandler::OnBeforeBrowse( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + cef_handler_navtype_t navType, + bool isRedirect) { + REQUIRE_UI_THREAD(); + return RequestHandler_OnBeforeBrowse( + browser, frame, request, navType, isRedirect); +} + +bool ClientHandler::OnBeforeResourceLoad( + CefRefPtr browser, + CefRefPtr request, + CefString& redirectUrl, + CefRefPtr& resourceStream, + CefRefPtr response, + int loadFlags) { + REQUIRE_IO_THREAD(); + return RequestHandler_OnBeforeResourceLoad( + browser, request, redirectUrl, resourceStream, response, loadFlags); +} + +void ClientHandler::OnResourceRedirect( + CefRefPtr browser, + const CefString& old_url, + CefString& new_url) { + REQUIRE_IO_THREAD(); + RequestHandler_OnResourceRedirect( + browser, const_cast(old_url), new_url); +} + +void ClientHandler::OnResourceResponse( + CefRefPtr browser, + const CefString& url, + CefRefPtr response, + CefRefPtr& filter) { + REQUIRE_UI_THREAD(); + RequestHandler_OnResourceResponse( + browser, const_cast(url), response, filter); +} + +bool ClientHandler::OnProtocolExecution( + CefRefPtr browser, + const CefString& url, + bool& allowOSExecution) { + REQUIRE_IO_THREAD(); + return RequestHandler_OnProtocolExecution( + browser, const_cast(url), allowOSExecution); +} + +bool ClientHandler::GetDownloadHandler( + CefRefPtr browser, + const CefString& mimeType, + const CefString& fileName, + int64 contentLength, + CefRefPtr& handler) { + // Multiple downloads at the same time? + AutoLock lock_scope(this); + REQUIRE_UI_THREAD(); + return RequestHandler_GetDownloadHandler(browser, mimeType, fileName, + contentLength, handler); +} + +bool ClientHandler::GetAuthCredentials( + CefRefPtr browser, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefString& username, + CefString& password) { + REQUIRE_IO_THREAD(); + return RequestHandler_GetAuthCredentials( + browser, isProxy, const_cast(host), port, + const_cast(realm), const_cast(scheme), + username, password); +} + +CefRefPtr ClientHandler::GetCookieManager( + CefRefPtr browser, + const CefString& main_url) { + REQUIRE_IO_THREAD(); + return RequestHandler_GetCookieManager( + browser, const_cast(main_url)); +} + +// ----------------------------------------------------------------------------- +// CefDisplayHandler +// ----------------------------------------------------------------------------- + +void ClientHandler::OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnAddressChange(browser, frame, const_cast(url)); +} + +bool ClientHandler::OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) { + REQUIRE_UI_THREAD(); + return DisplayHandler_OnConsoleMessage( + browser, const_cast(message), + const_cast(source), line); +} + +void ClientHandler::OnContentsSizeChange(CefRefPtr browser, + CefRefPtr frame, + int width, + int height) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnContentsSizeChange(browser, frame, width, height); +} + +void ClientHandler::OnNavStateChange(CefRefPtr browser, + bool canGoBack, + bool canGoForward) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward); +} + +void ClientHandler::OnStatusMessage(CefRefPtr browser, + const CefString& value, + StatusType type) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnStatusMessage(browser, const_cast(value), type); +} + + +void ClientHandler::OnTitleChange(CefRefPtr browser, + const CefString& title) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnTitleChange(browser, const_cast(title)); +} + +bool ClientHandler::OnTooltip(CefRefPtr browser, + CefString& text) { + REQUIRE_UI_THREAD(); + return DisplayHandler_OnTooltip(browser, text); +} + +// ----------------------------------------------------------------------------- +// CefLifeSpanHandler +// ----------------------------------------------------------------------------- + +bool ClientHandler::DoClose(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return LifespanHandler_DoClose(browser); +} + +void ClientHandler::OnAfterCreated(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + LifespanHandler_OnAfterCreated(browser); +} + +void ClientHandler::OnBeforeClose(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + LifespanHandler_OnBeforeClose(browser); +} + +bool ClientHandler::OnBeforePopup(CefRefPtr parentBrowser, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + CefRefPtr& client, + CefBrowserSettings& settings) { + REQUIRE_UI_THREAD(); + // @TODO + return false; +} + +bool ClientHandler::RunModal(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return LifespanHandler_RunModal(browser); +} + +// ----------------------------------------------------------------------------- +// CefRenderHandler +// ----------------------------------------------------------------------------- + +#if defined(OS_WIN) + +bool ClientHandler::GetViewRect(CefRefPtr browser, + CefRect& rect) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetViewRect(browser, rect); +} + +bool ClientHandler::GetScreenRect(CefRefPtr browser, + CefRect& rect) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetScreenRect(browser, rect); +} + +bool ClientHandler::GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetScreenPoint( + browser, viewX, viewY, screenX, screenY); +} + +void ClientHandler::OnPopupShow(CefRefPtr browser, + bool show) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPopupShow(browser, show); +} + +void ClientHandler::OnPopupSize(CefRefPtr browser, + const CefRect& rect) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPopupSize(browser, const_cast(rect)); +} + +void ClientHandler::OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPaint(browser, type, + const_cast(dirtyRects), + const_cast(buffer)); +} + +void ClientHandler::OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) { + REQUIRE_UI_THREAD(); + RenderHandler_OnCursorChange(browser, cursor); +} + +// #if defined(OS_WIN) - CefRenderHandler +#endif + +// ----------------------------------------------------------------------------- +// CefDragHandler +// ----------------------------------------------------------------------------- + +bool ClientHandler::OnDragStart(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { + REQUIRE_UI_THREAD(); + return DragHandler_OnDragStart(browser, dragData, mask); +} + +bool ClientHandler::OnDragEnter(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { + REQUIRE_UI_THREAD(); + return DragHandler_OnDragEnter(browser, dragData, mask); +} diff --git a/cefpython/cef1/client_handler/client_handler.h b/cefpython/cef1/client_handler/client_handler.h new file mode 100644 index 00000000..689a00ef --- /dev/null +++ b/cefpython/cef1/client_handler/client_handler.h @@ -0,0 +1,304 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class ClientHandler : public CefClient, + public CefLoadHandler, + public CefKeyboardHandler, + public CefV8ContextHandler, + public CefRequestHandler, + public CefDisplayHandler, + public CefLifeSpanHandler, + public CefRenderHandler, + public CefDragHandler +/* + public CefFocusHandler, + public CefMenuHandler, + public CefPrintHandler, + public CefPermissionHandler, + public CefFindHandler, + public CefJSDialogHandler, +*/ +{ +public: + ClientHandler(){} + virtual ~ClientHandler(){} + + // --------------------------------------------------------------------------- + // Handlers that are already implemented + // --------------------------------------------------------------------------- + + virtual CefRefPtr GetLoadHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetRequestHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetDisplayHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetKeyboardHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetV8ContextHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetLifeSpanHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetRenderHandler() OVERRIDE + { return this; } + + virtual CefRefPtr GetDragHandler() OVERRIDE + { return this; } + + // --------------------------------------------------------------------------- + // NOT yet implemented handlers + // --------------------------------------------------------------------------- + + virtual CefRefPtr GetFocusHandler() OVERRIDE + { return NULL; } + + virtual CefRefPtr GetMenuHandler() OVERRIDE + { return NULL; } + + virtual CefRefPtr GetPermissionHandler() OVERRIDE + { return NULL; } + + virtual CefRefPtr GetPrintHandler() OVERRIDE + { return NULL; } + + virtual CefRefPtr GetFindHandler() OVERRIDE + { return NULL; } + + virtual CefRefPtr GetJSDialogHandler() OVERRIDE + { return NULL; } + + // --------------------------------------------------------------------------- + // CefLoadHandler methods. + // --------------------------------------------------------------------------- + + virtual void OnLoadEnd( + CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode + ) OVERRIDE; + + + virtual void OnLoadStart( + CefRefPtr browser, + CefRefPtr frame + ) OVERRIDE; + + virtual bool OnLoadError( + CefRefPtr browser, + CefRefPtr frame, + cef_handler_errorcode_t errorCode, + const CefString& failedUrl, + CefString& errorText + ) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefKeyboardHandler methods. + // --------------------------------------------------------------------------- + + virtual bool OnKeyEvent( + CefRefPtr browser, + cef_handler_keyevent_type_t eventType, + int keyCode, + int modifiers, + bool isSystemKey, + bool isAfterJavascript + ) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefV8ContextHandler methods. + // --------------------------------------------------------------------------- + + virtual void OnContextCreated( + CefRefPtr cefBrowser, + CefRefPtr cefFrame, + CefRefPtr v8Context) OVERRIDE; + + virtual void OnContextReleased( + CefRefPtr cefBrowser, + CefRefPtr cefFrame, + CefRefPtr v8Context) OVERRIDE; + + virtual void OnUncaughtException( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefRequestHandler methods. + // --------------------------------------------------------------------------- + + virtual bool OnBeforeBrowse( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + cef_handler_navtype_t navType, + bool isRedirect) OVERRIDE; + + virtual bool OnBeforeResourceLoad( + CefRefPtr browser, + CefRefPtr request, + CefString& redirectUrl, + CefRefPtr& resourceStream, + CefRefPtr response, + int loadFlags) OVERRIDE; + + virtual void OnResourceRedirect( + CefRefPtr browser, + const CefString& old_url, + CefString& new_url) OVERRIDE; + + virtual void OnResourceResponse( + CefRefPtr browser, + const CefString& url, + CefRefPtr response, + CefRefPtr& filter) OVERRIDE; + + virtual bool OnProtocolExecution( + CefRefPtr browser, + const CefString& url, + bool& allowOSExecution) OVERRIDE; + + virtual bool GetDownloadHandler( + CefRefPtr browser, + const CefString& mimeType, + const CefString& fileName, + int64 contentLength, + CefRefPtr& handler) OVERRIDE; + + virtual bool GetAuthCredentials( + CefRefPtr browser, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefString& username, + CefString& password) OVERRIDE; + + virtual CefRefPtr GetCookieManager( + CefRefPtr browser, + const CefString& main_url) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefDisplayHandler + // --------------------------------------------------------------------------- + + virtual void OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) OVERRIDE; + + virtual bool OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) OVERRIDE; + + virtual void OnContentsSizeChange(CefRefPtr browser, + CefRefPtr frame, + int width, + int height) OVERRIDE; + + virtual void OnNavStateChange(CefRefPtr browser, + bool canGoBack, + bool canGoForward) OVERRIDE; + + virtual void OnStatusMessage(CefRefPtr browser, + const CefString& value, + StatusType type) OVERRIDE; + + virtual void OnTitleChange(CefRefPtr browser, + const CefString& title) OVERRIDE; + + virtual bool OnTooltip(CefRefPtr browser, + CefString& text) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefLifeSpanHandler + // --------------------------------------------------------------------------- + + virtual bool DoClose(CefRefPtr browser) OVERRIDE; + + virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; + + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + + virtual bool OnBeforePopup(CefRefPtr parentBrowser, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + CefRefPtr& client, + CefBrowserSettings& settings) OVERRIDE; + + virtual bool RunModal(CefRefPtr browser) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefRenderHandler + // --------------------------------------------------------------------------- + +#if defined(OS_WIN) + + virtual bool GetViewRect(CefRefPtr browser, + CefRect& rect) OVERRIDE; + + virtual bool GetScreenRect(CefRefPtr browser, + CefRect& rect) OVERRIDE; + + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) OVERRIDE; + + virtual void OnPopupShow(CefRefPtr browser, + bool show) OVERRIDE; + + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) OVERRIDE; + + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer) OVERRIDE; + + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) OVERRIDE; + +#endif + + // --------------------------------------------------------------------------- + // CefDragHandler + // --------------------------------------------------------------------------- + + virtual bool OnDragStart(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) OVERRIDE; + + virtual bool OnDragEnter(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) OVERRIDE; + +protected: + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ClientHandler); + + // Include the default locking implementation. + IMPLEMENT_LOCKING(ClientHandler); + +}; diff --git a/cefpython/cef1/client_handler/client_handler.sln b/cefpython/cef1/client_handler/client_handler.sln new file mode 100644 index 00000000..b3dd2d2a --- /dev/null +++ b/cefpython/cef1/client_handler/client_handler.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_handler_py27", "client_handler_py27.vcproj", "{15AD928F-FFD0-4FA5-B469-E42ABB0B4196}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC943}") = "client_handler_py32", "client_handler_py32.vcproj", "{37AA7CD9-67AD-40B1-ADC0-D62173764BCA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15AD928F-FFD0-4FA5-B469-E42ABB0B4196}.Debug|Win32.ActiveCfg = Debug|Win32 + {15AD928F-FFD0-4FA5-B469-E42ABB0B4196}.Debug|Win32.Build.0 = Debug|Win32 + {15AD928F-FFD0-4FA5-B469-E42ABB0B4196}.Release|Win32.ActiveCfg = Release|Win32 + {15AD928F-FFD0-4FA5-B469-E42ABB0B4196}.Release|Win32.Build.0 = Release|Win32 + {37AA7CD9-67AD-40B1-ADC0-D62173764BCA}.Debug|Win32.ActiveCfg = Debug|Win32 + {37AA7CD9-67AD-40B1-ADC0-D62173764BCA}.Debug|Win32.Build.0 = Debug|Win32 + {37AA7CD9-67AD-40B1-ADC0-D62173764BCA}.Release|Win32.ActiveCfg = Release|Win32 + {37AA7CD9-67AD-40B1-ADC0-D62173764BCA}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cefpython/cef1/client_handler/client_handler_py27.vcproj b/cefpython/cef1/client_handler/client_handler_py27.vcproj new file mode 100644 index 00000000..3f45e736 --- /dev/null +++ b/cefpython/cef1/client_handler/client_handler_py27.vcproj @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/client_handler/client_handler_py32.vcproj b/cefpython/cef1/client_handler/client_handler_py32.vcproj new file mode 100644 index 00000000..643a6751 --- /dev/null +++ b/cefpython/cef1/client_handler/client_handler_py32.vcproj @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/client_handler/content_filter_handler.cpp b/cefpython/cef1/client_handler/content_filter_handler.cpp new file mode 100644 index 00000000..0578bf5d --- /dev/null +++ b/cefpython/cef1/client_handler/content_filter_handler.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "content_filter_handler.h" + +void ContentFilterHandler::ProcessData(const void* data, int data_size, + CefRefPtr& substitute_data) { + REQUIRE_UI_THREAD(); + ContentFilterHandler_ProcessData(contentFilterId_, data, data_size, + substitute_data); +} + +void ContentFilterHandler::Drain(CefRefPtr& remainder) { + REQUIRE_UI_THREAD(); + ContentFilterHandler_Drain(contentFilterId_, remainder); +} \ No newline at end of file diff --git a/cefpython/cef1/client_handler/content_filter_handler.h b/cefpython/cef1/client_handler/content_filter_handler.h new file mode 100644 index 00000000..ee267ac4 --- /dev/null +++ b/cefpython/cef1/client_handler/content_filter_handler.h @@ -0,0 +1,31 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class ContentFilterHandler : public CefContentFilter +{ +public: + int contentFilterId_; +public: + ContentFilterHandler(int contentFilterId) : + contentFilterId_(contentFilterId) { + } + virtual ~ContentFilterHandler(){} + + virtual void ProcessData(const void* data, int data_size, + CefRefPtr& substitute_data) OVERRIDE; + + virtual void Drain(CefRefPtr& remainder) OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ContentFilterHandler); +}; diff --git a/cefpython/cef1/client_handler/cookie_visitor.cpp b/cefpython/cef1/client_handler/cookie_visitor.cpp new file mode 100644 index 00000000..f1e362da --- /dev/null +++ b/cefpython/cef1/client_handler/cookie_visitor.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "cookie_visitor.h" +#include + +bool CookieVisitor::Visit( + const CefCookie& cookie, + int count, + int total, + bool& deleteCookie + ) { + REQUIRE_IO_THREAD(); + return CookieVisitor_Visit(cookieVisitorId_, cookie, count, total, deleteCookie); +} diff --git a/cefpython/cef1/client_handler/cookie_visitor.h b/cefpython/cef1/client_handler/cookie_visitor.h new file mode 100644 index 00000000..b33a8f6e --- /dev/null +++ b/cefpython/cef1/client_handler/cookie_visitor.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class CookieVisitor : public CefCookieVisitor +{ +public: + int cookieVisitorId_; +public: + CookieVisitor(int cookieVisitorId) + : cookieVisitorId_(cookieVisitorId) { + } + + virtual bool Visit( + const CefCookie& cookie, + int count, + int total, + bool& deleteCookie + ) OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(CookieVisitor); +}; diff --git a/cefpython/cef1/client_handler/download_handler.cpp b/cefpython/cef1/client_handler/download_handler.cpp new file mode 100644 index 00000000..7f8b60aa --- /dev/null +++ b/cefpython/cef1/client_handler/download_handler.cpp @@ -0,0 +1,25 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "download_handler.h" +#include + +bool DownloadHandler::ReceivedData( + void* data, + int data_size + ) { + // Multiple downloads at the same time? + AutoLock lock_scope(this); + REQUIRE_UI_THREAD(); + if (data_size == 0) + return true; + return DownloadHandler_ReceivedData(downloadHandlerId_, data, data_size); +} + +void DownloadHandler::Complete() { + // Multiple downloads at the same time? + AutoLock lock_scope(this); + REQUIRE_UI_THREAD(); + DownloadHandler_Complete(downloadHandlerId_); +} diff --git a/cefpython/cef1/client_handler/download_handler.h b/cefpython/cef1/client_handler/download_handler.h new file mode 100644 index 00000000..ad802965 --- /dev/null +++ b/cefpython/cef1/client_handler/download_handler.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class DownloadHandler : public CefDownloadHandler +{ +public: + int downloadHandlerId_; +public: + DownloadHandler(int downloadHandlerId) + : downloadHandlerId_(downloadHandlerId) { + } + + virtual bool ReceivedData(void* data, int data_size) OVERRIDE; + virtual void Complete() OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(DownloadHandler); + // Include the default locking implementation. + IMPLEMENT_LOCKING(DownloadHandler); +}; diff --git a/cefpython/cef1/client_handler/web_request_client.cpp b/cefpython/cef1/client_handler/web_request_client.cpp new file mode 100644 index 00000000..2f5039f1 --- /dev/null +++ b/cefpython/cef1/client_handler/web_request_client.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "web_request_client.h" + +// Cython doesn't know nothing about 'const' so we need to remove it, +// otherwise you get compile error. + +void WebRequestClient::OnStateChange(CefRefPtr requester, + RequestState state) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnStateChange(webRequestId_, requester, state); +} + +void WebRequestClient::OnRedirect(CefRefPtr requester, + CefRefPtr request, + CefRefPtr response) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnRedirect(webRequestId_, requester, request, response); +} + +void WebRequestClient::OnHeadersReceived(CefRefPtr requester, + CefRefPtr response) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnHeadersReceived(webRequestId_, requester, response); +} + +void WebRequestClient::OnProgress(CefRefPtr requester, + uint64 bytesSent, uint64 totalBytesToBeSent) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnProgress(webRequestId_, requester, bytesSent, + totalBytesToBeSent); +} + +void WebRequestClient::OnData(CefRefPtr requester, + const void* data, int dataLength) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnData(webRequestId_, requester, const_cast(data), + dataLength); +} + +void WebRequestClient::OnError(CefRefPtr requester, + ErrorCode errorCode) { + REQUIRE_UI_THREAD(); + WebRequestClient_OnError(webRequestId_, requester, errorCode); +} diff --git a/cefpython/cef1/client_handler/web_request_client.h b/cefpython/cef1/client_handler/web_request_client.h new file mode 100644 index 00000000..0a8eb996 --- /dev/null +++ b/cefpython/cef1/client_handler/web_request_client.h @@ -0,0 +1,44 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class WebRequestClient : public CefWebURLRequestClient +{ +public: + int webRequestId_; +public: + WebRequestClient(int webRequestId) : + webRequestId_(webRequestId) { + } + virtual ~WebRequestClient(){} + + virtual void OnStateChange(CefRefPtr requester, + RequestState state) OVERRIDE; + + virtual void OnRedirect(CefRefPtr requester, + CefRefPtr request, + CefRefPtr response) OVERRIDE; + + virtual void OnHeadersReceived(CefRefPtr requester, + CefRefPtr response) OVERRIDE; + + virtual void OnProgress(CefRefPtr requester, + uint64 bytesSent, uint64 totalBytesToBeSent) OVERRIDE; + + virtual void OnData(CefRefPtr requester, + const void* data, int dataLength) OVERRIDE; + + virtual void OnError(CefRefPtr requester, + ErrorCode errorCode) OVERRIDE; +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(WebRequestClient); +}; diff --git a/cefpython/cef1/http_authentication/AuthCredentials.cpp b/cefpython/cef1/http_authentication/AuthCredentials.cpp new file mode 100644 index 00000000..054f0006 --- /dev/null +++ b/cefpython/cef1/http_authentication/AuthCredentials.cpp @@ -0,0 +1,3 @@ +#include "AuthCredentials.h" + +AuthCredentialsDataMap AuthCredentials::data; diff --git a/cefpython/cef1/http_authentication/AuthCredentials.h b/cefpython/cef1/http_authentication/AuthCredentials.h new file mode 100644 index 00000000..909c4b8b --- /dev/null +++ b/cefpython/cef1/http_authentication/AuthCredentials.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include + +typedef struct +{ + std::string username; + std::string password; +} AuthCredentialsData; + +typedef std::map AuthCredentialsDataMap; + +class AuthCredentials +{ +public: + static void SetData(HWND hwnd, AuthCredentialsData* newData) + { + data[hwnd] = newData; + } + static AuthCredentialsData* GetData(HWND hwnd) + { + if (data.find(hwnd) == data.end()) { + return NULL; + } + return data[hwnd]; + } +protected: + static AuthCredentialsDataMap data; +}; diff --git a/cefpython/cef1/http_authentication/AuthDialog.cpp b/cefpython/cef1/http_authentication/AuthDialog.cpp new file mode 100644 index 00000000..7e18aeb1 --- /dev/null +++ b/cefpython/cef1/http_authentication/AuthDialog.cpp @@ -0,0 +1,87 @@ +#include "AuthDialog.h" +#include "DialogTemplate.h" +#include + +AuthCredentialsData* AuthDialog(HWND parent) +{ + // We want close button, but no sysmenu. + DialogTemplate dialogTemplate("Http Authentication", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | DS_CENTER, + WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE, 10, 10, 257, 80, "Tahoma", 8); + dialogTemplate.AddStatic("Username:", WS_VISIBLE, 0, 2 + 3, 7, 37, 8, -1); + dialogTemplate.AddStatic("Password:", WS_VISIBLE, 0, 2 + 3, 24, 37, 8, -1); + dialogTemplate.AddEditBox("", WS_VISIBLE | WS_TABSTOP, WS_EX_STATICEDGE, 45 + 3, 7, 80, 10, HTTP_AUTHENTICATION_USERNAME); + dialogTemplate.AddEditBox("", WS_VISIBLE | WS_TABSTOP | ES_PASSWORD, WS_EX_STATICEDGE, 45 + 3, 24, 80, 10, HTTP_AUTHENTICATION_PASSWORD); + dialogTemplate.AddButton("OK", WS_VISIBLE | WS_TABSTOP, 0, 2 + 3, 41, 48, 13, HTTP_AUTHENTICATION_OK); + dialogTemplate.AddButton("Cancel", WS_VISIBLE | WS_TABSTOP, 0, 55 + 3, 41, 48, 13, HTTP_AUTHENTICATION_CANCEL); + + INT_PTR ret = DialogBoxIndirect(GetModuleHandle(0), dialogTemplate, parent, (DLGPROC)AuthDialogProc); + if (1 == ret) { + // OK. + AuthCredentialsData* credentialsData = AuthCredentials::GetData(parent); + if (credentialsData == NULL) { + // Wrong HWND, parent == innerWindowID, + // but in AuthDialogProc() > GetWindow(hDlg, GW_OWNER) returned topWindowID. + HWND tryParent = GetParent(parent); + if (!tryParent) { + // GetParent() works fine, calling GW_OWNER just in case. + // Yes, the order is the reversed compared to what is in AuthDialogProc(). + tryParent = GetWindow(parent, GW_OWNER); + } + credentialsData = AuthCredentials::GetData(tryParent); + } + return credentialsData; + } else { + // Cancel. + return NULL; + } +} + +INT_PTR CALLBACK AuthDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND parent; + AuthCredentialsData* credentialsData; + TCHAR text[128]; + + switch (msg) + { + case WM_INITDIALOG: + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case HTTP_AUTHENTICATION_OK: // OK button. + case IDOK: // Enter. + + parent = GetWindow(hDlg, GW_OWNER); + if (!parent) { + // GW_OWNER works fine, calling GetParent just in case. + // Yes, the order is reversed compared to what is in AuthDialog(). + parent = GetParent(hDlg); + } + + credentialsData = AuthCredentials::GetData(parent); + if (credentialsData == NULL) { + credentialsData = new AuthCredentialsData(); + } + + GetDlgItemText(hDlg, HTTP_AUTHENTICATION_USERNAME, text, 128); + credentialsData->username.assign(text, 128); + + GetDlgItemText(hDlg, HTTP_AUTHENTICATION_PASSWORD, text, 128); + credentialsData->password.assign(text, 128); + + AuthCredentials::SetData(parent, credentialsData); + + EndDialog(hDlg, 1); + return TRUE; + + case HTTP_AUTHENTICATION_CANCEL: // Cancel button. + case IDCANCEL: // Close Button or Escape key. + EndDialog(hDlg, 2); + return TRUE; + } + break; + } + return FALSE; +} diff --git a/cefpython/cef1/http_authentication/AuthDialog.h b/cefpython/cef1/http_authentication/AuthDialog.h new file mode 100644 index 00000000..9c55ed48 --- /dev/null +++ b/cefpython/cef1/http_authentication/AuthDialog.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include "AuthCredentials.h" + +#define HTTP_AUTHENTICATION_USERNAME 1001 +#define HTTP_AUTHENTICATION_PASSWORD 1002 +#define HTTP_AUTHENTICATION_OK 1003 +#define HTTP_AUTHENTICATION_CANCEL 1004 + +AuthCredentialsData* AuthDialog(HWND parent); +INT_PTR CALLBACK AuthDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); + diff --git a/cefpython/cef1/http_authentication/DialogTemplate.cpp b/cefpython/cef1/http_authentication/DialogTemplate.cpp new file mode 100644 index 00000000..b9236d30 --- /dev/null +++ b/cefpython/cef1/http_authentication/DialogTemplate.cpp @@ -0,0 +1,236 @@ +// DialogTemplate - taken from here: +// http://www.flipcode.com/archives/Dialog_Template.shtml +// http://www.flipcode.com/archives/An_assert_Replacement.shtml + +#include "DialogTemplate.h" + +DialogTemplate::DialogTemplate(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, + LPCSTR font, WORD fontSize) + { + + usedBufferLength = sizeof(DLGTEMPLATE ); + totalBufferLength = usedBufferLength; + + dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength); + + dialogTemplate->style = style; + + if (font != NULL) + { + dialogTemplate->style |= DS_SETFONT; + } + + dialogTemplate->x = x; + dialogTemplate->y = y; + dialogTemplate->cx = w; + dialogTemplate->cy = h; + dialogTemplate->cdit = 0; + + dialogTemplate->dwExtendedStyle = exStyle; + + // The dialog box doesn't have a menu or a special class + + AppendData("\0", 2); + AppendData("\0", 2); + + // Add the dialog's caption to the template + + AppendString(caption); + + if (font != NULL) + { + AppendData(&fontSize, sizeof(WORD)); + AppendString(font); + } + + } + +void DialogTemplate::AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle, + int x, int y, int w, int h, WORD id) + { + + DLGITEMTEMPLATE item; + + item.style = style; + item.x = x; + item.y = y; + item.cx = w; + item.cy = h; + item.id = id; + + item.dwExtendedStyle = exStyle; + + AppendData(&item, sizeof(DLGITEMTEMPLATE)); + + AppendString(type); + AppendString(caption); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + // Increment the component count + + dialogTemplate->cdit++; + + } + +void DialogTemplate::AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + +void DialogTemplate::AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + +void DialogTemplate::AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + +void DialogTemplate::AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0083, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + +void DialogTemplate::AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0084, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + +void DialogTemplate::AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id) + { + + AddStandardComponent(0x0085, caption, style, exStyle, x, y, w, h, id); + + WORD creationDataLength = 0; + AppendData(&creationDataLength, sizeof(WORD)); + + } + + /** + * Returns a pointer to the Win32 dialog template which the object + * represents. This pointer may become invalid if additional + * components are added to the template. + */ + + +void DialogTemplate::AddStandardComponent(WORD type, LPCSTR caption, DWORD style, + DWORD exStyle, int x, int y, int w, int h, WORD id) + { + + DLGITEMTEMPLATE item; + + // DWORD algin the beginning of the component data + + AlignData(sizeof(DWORD)); + + item.style = style; + item.x = x; + item.y = y; + item.cx = w; + item.cy = h; + item.id = id; + + item.dwExtendedStyle = exStyle; + + AppendData(&item, sizeof(DLGITEMTEMPLATE)); + + WORD preType = 0xFFFF; + + AppendData(&preType, sizeof(WORD)); + AppendData(&type, sizeof(WORD)); + + AppendString(caption); + + // Increment the component count + + dialogTemplate->cdit++; + + } + +void DialogTemplate::AlignData(int size) + { + + int paddingSize = usedBufferLength % size; + + if (paddingSize != 0) + { + EnsureSpace(paddingSize); + usedBufferLength += paddingSize; + } + + } + +void DialogTemplate::AppendString(LPCSTR string) + { + + int length = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0); + + WCHAR* wideString = (WCHAR*)malloc(sizeof(WCHAR) * length); + MultiByteToWideChar(CP_ACP, 0, string, -1, wideString, length); + + AppendData(wideString, length * sizeof(WCHAR)); + free(wideString); + + } + +void DialogTemplate::AppendData(void* data, int dataLength) + { + + EnsureSpace(dataLength); + + memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength); + usedBufferLength += dataLength; + + } + +void DialogTemplate::EnsureSpace(int length) + { + + if (length + usedBufferLength > totalBufferLength) + { + + totalBufferLength += length * 2; + + void* newBuffer = malloc(totalBufferLength); + memcpy(newBuffer, dialogTemplate, usedBufferLength); + + free(dialogTemplate); + dialogTemplate = (DLGTEMPLATE*)newBuffer; + + } + + } diff --git a/cefpython/cef1/http_authentication/DialogTemplate.h b/cefpython/cef1/http_authentication/DialogTemplate.h new file mode 100644 index 00000000..f7b8ae52 --- /dev/null +++ b/cefpython/cef1/http_authentication/DialogTemplate.h @@ -0,0 +1,68 @@ +#pragma once + +// DialogTemplate - taken from here: +// http://www.flipcode.com/archives/Dialog_Template.shtml +// http://www.flipcode.com/archives/An_assert_Replacement.shtml + +#include + +class DialogTemplate +{ + +public: + + DialogTemplate(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, + LPCSTR font, WORD fontSize); + + void AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle, + int x, int y, int w, int h, WORD id); + + void AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + void AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + void AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + void AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + void AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + void AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, + int w, int h, WORD id); + + operator const DLGTEMPLATE*() const + { + return dialogTemplate; + } + + virtual ~DialogTemplate() + { + free(dialogTemplate); + } + +protected: + + void AddStandardComponent(WORD type, LPCSTR caption, DWORD style, + DWORD exStyle, int x, int y, int w, int h, WORD id); + + void AlignData(int size); + + void AppendString(LPCSTR string); + + void AppendData(void* data, int dataLength); + + void EnsureSpace(int length); + +private: + + DLGTEMPLATE* dialogTemplate; + + int totalBufferLength; + int usedBufferLength; + +}; \ No newline at end of file diff --git a/cefpython/cef1/http_authentication/http_authentication.sln b/cefpython/cef1/http_authentication/http_authentication.sln new file mode 100644 index 00000000..d8ff6055 --- /dev/null +++ b/cefpython/cef1/http_authentication/http_authentication.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "http_authentication", "http_authentication.vcproj", "{25F1A352-E0AA-4F1A-8134-CB5409953AE9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {25F1A352-E0AA-4F1A-8134-CB5409953AE9}.Debug|Win32.ActiveCfg = Debug|Win32 + {25F1A352-E0AA-4F1A-8134-CB5409953AE9}.Debug|Win32.Build.0 = Debug|Win32 + {25F1A352-E0AA-4F1A-8134-CB5409953AE9}.Release|Win32.ActiveCfg = Release|Win32 + {25F1A352-E0AA-4F1A-8134-CB5409953AE9}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cefpython/cef1/http_authentication/http_authentication.vcproj b/cefpython/cef1/http_authentication/http_authentication.vcproj new file mode 100644 index 00000000..bd610b43 --- /dev/null +++ b/cefpython/cef1/http_authentication/http_authentication.vcproj @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/include/cef_app.h b/cefpython/cef1/include/cef_app.h new file mode 100644 index 00000000..e352ebba --- /dev/null +++ b/cefpython/cef1/include/cef_app.h @@ -0,0 +1,139 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_APP_H_ +#define CEF_INCLUDE_CEF_APP_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_proxy_handler.h" +#include "include/cef_resource_bundle_handler.h" +#include "include/cef_scheme.h" + +class CefApp; + +/// +// This function should be called on the main application thread to initialize +// CEF when the application is started. The |application| parameter may be +// empty. A return value of true indicates that it succeeded and false indicates +// that it failed. +/// +/*--cef(revision_check,optional_param=application)--*/ +bool CefInitialize(const CefSettings& settings, CefRefPtr application); + +/// +// This function should be called on the main application thread to shut down +// CEF before the application exits. +/// +/*--cef()--*/ +void CefShutdown(); + +/// +// Perform a single iteration of CEF message loop processing. This function is +// used to integrate the CEF message loop into an existing application message +// loop. Care must be taken to balance performance against excessive CPU usage. +// This function should only be called on the main application thread and only +// if CefInitialize() is called with a CefSettings.multi_threaded_message_loop +// value of false. This function will not block. +/// +/*--cef()--*/ +void CefDoMessageLoopWork(); + +/// +// Run the CEF message loop. Use this function instead of an application- +// provided message loop to get the best balance between performance and CPU +// usage. This function should only be called on the main application thread and +// only if CefInitialize() is called with a +// CefSettings.multi_threaded_message_loop value of false. This function will +// block until a quit message is received by the system. +/// +/*--cef()--*/ +void CefRunMessageLoop(); + +/// +// Quit the CEF message loop that was started by calling CefRunMessageLoop(). +// This function should only be called on the main application thread and only +// if CefRunMessageLoop() was used. +/// +/*--cef()--*/ +void CefQuitMessageLoop(); + +/// +// Set to true before calling Windows APIs like TrackPopupMenu that enter a +// modal message loop. Set to false after exiting the modal message loop. +/// +/*--cef()--*/ +void CefSetOSModalLoop(bool osModalLoop); + +/// +// Implement this interface to provide handler implementations. Methods will be +// called on the thread indicated. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefApp : public virtual CefBase { + public: + /// + // Provides an opportunity to register custom schemes. Do not keep a reference + // to the |registrar| object. This method is called on the UI thread. + /// + /*--cef()--*/ + virtual void OnRegisterCustomSchemes( + CefRefPtr registrar) { + } + + /// + // Return the handler for resource bundle events. If + // CefSettings.pack_loading_disabled is true a handler must be returned. If no + // handler is returned resources will be loaded from pack files. This method + // is called on multiple threads. + /// + /*--cef()--*/ + virtual CefRefPtr GetResourceBundleHandler() { + return NULL; + } + + /// + // Return the handler for proxy events. If not handler is returned the default + // system handler will be used. This method is called on the IO thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetProxyHandler() { + return NULL; + } +}; + +#endif // CEF_INCLUDE_CEF_APP_H_ diff --git a/cefpython/cef1/include/cef_application_mac.h b/cefpython/cef1/include/cef_application_mac.h new file mode 100644 index 00000000..33042478 --- /dev/null +++ b/cefpython/cef1/include/cef_application_mac.h @@ -0,0 +1,120 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_CEF_APPLICATION_MAC_H_ +#define CEF_INCLUDE_CEF_APPLICATION_MAC_H_ +#pragma once + +#include "include/cef_base.h" + +#if defined(OS_MACOSX) && defined(__OBJC__) + +#ifdef BUILDING_CEF_SHARED + +// Use the existing CrAppProtocol definition. +#include "base/message_pump_mac.h" + +// Use the existing empty protocol definitions. +#import "base/mac/cocoa_protocols.h" + +#else // BUILDING_CEF_SHARED + +#import +#import + +// Copy of CrAppProtocol definition from base/message_pump_mac.h. +@protocol CrAppProtocol +// Must return true if -[NSApplication sendEvent:] is currently on the stack. +- (BOOL)isHandlingSendEvent; +@end + +// The Mac OS X 10.6 SDK introduced new protocols used for delegates. These +// protocol defintions were not present in earlier releases of the Mac OS X +// SDK. In order to support building against the new SDK, which requires +// delegates to conform to these protocols, and earlier SDKs, which do not +// define these protocols at all, this file will provide empty protocol +// definitions when used with earlier SDK versions. + +#if !defined(MAC_OS_X_VERSION_10_6) || \ +MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + +#define DEFINE_EMPTY_PROTOCOL(p) \ +@protocol p \ +@end + +DEFINE_EMPTY_PROTOCOL(NSAlertDelegate) +DEFINE_EMPTY_PROTOCOL(NSApplicationDelegate) +DEFINE_EMPTY_PROTOCOL(NSControlTextEditingDelegate) +DEFINE_EMPTY_PROTOCOL(NSMatrixDelegate) +DEFINE_EMPTY_PROTOCOL(NSMenuDelegate) +DEFINE_EMPTY_PROTOCOL(NSOpenSavePanelDelegate) +DEFINE_EMPTY_PROTOCOL(NSOutlineViewDataSource) +DEFINE_EMPTY_PROTOCOL(NSOutlineViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSSpeechSynthesizerDelegate) +DEFINE_EMPTY_PROTOCOL(NSSplitViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSTableViewDataSource) +DEFINE_EMPTY_PROTOCOL(NSTableViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSTextFieldDelegate) +DEFINE_EMPTY_PROTOCOL(NSTextViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSWindowDelegate) + +#undef DEFINE_EMPTY_PROTOCOL + +#endif + +#endif // BUILDING_CEF_SHARED + +// All CEF client applications must subclass NSApplication and implement this +// protocol. +@protocol CefAppProtocol +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent; +@end + +// Controls the state of |isHandlingSendEvent| in the event loop so that it is +// reset properly. +class CefScopedSendingEvent { + public: + CefScopedSendingEvent() + : app_(static_cast*>( + [NSApplication sharedApplication])), + handling_([app_ isHandlingSendEvent]) { + [app_ setHandlingSendEvent:YES]; + } + ~CefScopedSendingEvent() { + [app_ setHandlingSendEvent:handling_]; + } + + private: + NSApplication* app_; + BOOL handling_; +}; + +#endif // defined(OS_MACOSX) && defined(__OBJC__) + +#endif // CEF_INCLUDE_CEF_APPLICATION_MAC_H_ diff --git a/cefpython/cef1/include/cef_base.h b/cefpython/cef1/include/cef_base.h new file mode 100644 index 00000000..5fc964fa --- /dev/null +++ b/cefpython/cef1/include/cef_base.h @@ -0,0 +1,154 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_BASE_H_ +#define CEF_INCLUDE_CEF_BASE_H_ +#pragma once + +#include "include/internal/cef_build.h" +#include "include/internal/cef_ptr.h" +#include "include/internal/cef_types_wrappers.h" + +// Bring in platform-specific definitions. +#if defined(OS_WIN) +#include "include/internal/cef_win.h" +#elif defined(OS_MACOSX) +#include "include/internal/cef_mac.h" +#elif defined(OS_LINUX) +#include "include/internal/cef_linux.h" +#endif + +/// +// Interface defining the reference count implementation methods. All framework +// classes must extend the CefBase class. +/// +class CefBase { + public: + /// + // The AddRef method increments the reference count for the object. It should + // be called for every new copy of a pointer to a given object. The resulting + // reference count value is returned and should be used for diagnostic/testing + // purposes only. + /// + virtual int AddRef() =0; + + /// + // The Release method decrements the reference count for the object. If the + // reference count on the object falls to 0, then the object should free + // itself from memory. The resulting reference count value is returned and + // should be used for diagnostic/testing purposes only. + /// + virtual int Release() =0; + + /// + // Return the current number of references. + /// + virtual int GetRefCt() =0; + + protected: + virtual ~CefBase() {} +}; + + +/// +// Class that implements atomic reference counting. +/// +class CefRefCount { + public: + CefRefCount() : refct_(0) {} + + /// + // Atomic reference increment. + /// + int AddRef() { + return CefAtomicIncrement(&refct_); + } + + /// + // Atomic reference decrement. Delete the object when no references remain. + /// + int Release() { + return CefAtomicDecrement(&refct_); + } + + /// + // Return the current number of references. + /// + int GetRefCt() { return refct_; } + + private: + long refct_; // NOLINT(runtime/int) +}; + +/// +// Macro that provides a reference counting implementation for classes extending +// CefBase. +/// +#define IMPLEMENT_REFCOUNTING(ClassName) \ + public: \ + int AddRef() { return refct_.AddRef(); } \ + int Release() { \ + int retval = refct_.Release(); \ + if (retval == 0) \ + delete this; \ + return retval; \ + } \ + int GetRefCt() { return refct_.GetRefCt(); } \ + private: \ + CefRefCount refct_; + +/// +// Macro that provides a locking implementation. Use the Lock() and Unlock() +// methods to protect a section of code from simultaneous access by multiple +// threads. The AutoLock class is a helper that will hold the lock while in +// scope. +/// +#define IMPLEMENT_LOCKING(ClassName) \ + public: \ + class AutoLock { \ + public: \ + explicit AutoLock(ClassName* base) : base_(base) { base_->Lock(); } \ + ~AutoLock() { base_->Unlock(); } \ + private: \ + ClassName* base_; \ + }; \ + void Lock() { critsec_.Lock(); } \ + void Unlock() { critsec_.Unlock(); } \ + private: \ + CefCriticalSection critsec_; + +#endif // CEF_INCLUDE_CEF_BASE_H_ diff --git a/cefpython/cef1/include/cef_browser.h b/cefpython/cef1/include/cef_browser.h new file mode 100644 index 00000000..4f3508f3 --- /dev/null +++ b/cefpython/cef1/include/cef_browser.h @@ -0,0 +1,344 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_BROWSER_H_ +#define CEF_INCLUDE_CEF_BROWSER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_frame.h" +#include + +class CefClient; + +/// +// Class used to represent a browser window. The methods of this class may be +// called on any thread unless otherwise indicated in the comments. +/// +/*--cef(source=library)--*/ +class CefBrowser : public virtual CefBase { + public: + typedef cef_key_type_t KeyType; + typedef cef_mouse_button_type_t MouseButtonType; + typedef cef_paint_element_type_t PaintElementType; + + /// + // Create a new browser window using the window parameters specified by + // |windowInfo|. All values will be copied internally and the actual window + // will be created on the UI thread. This method call will not block. + /// + /*--cef(optional_param=url)--*/ + static bool CreateBrowser(CefWindowInfo& windowInfo, + CefRefPtr client, + const CefString& url, + const CefBrowserSettings& settings); + + /// + // Create a new browser window using the window parameters specified by + // |windowInfo|. This method should only be called on the UI thread. + /// + /*--cef(optional_param=url)--*/ + static CefRefPtr CreateBrowserSync(CefWindowInfo& windowInfo, + CefRefPtr client, + const CefString& url, + const CefBrowserSettings& settings); + + /// + // Call this method before destroying a contained browser window. This method + // performs any internal cleanup that may be needed before the browser window + // is destroyed. + /// + /*--cef()--*/ + virtual void ParentWindowWillClose() =0; + + /// + // Closes this browser window. + /// + /*--cef()--*/ + virtual void CloseBrowser() =0; + + /// + // Returns true if the browser can navigate backwards. + /// + /*--cef()--*/ + virtual bool CanGoBack() =0; + /// + // Navigate backwards. + /// + /*--cef()--*/ + virtual void GoBack() =0; + /// + // Returns true if the browser can navigate forwards. + /// + /*--cef()--*/ + virtual bool CanGoForward() =0; + /// + // Navigate forwards. + /// + /*--cef()--*/ + virtual void GoForward() =0; + /// + // Reload the current page. + /// + /*--cef()--*/ + virtual void Reload() =0; + /// + // Reload the current page ignoring any cached data. + /// + /*--cef()--*/ + virtual void ReloadIgnoreCache() =0; + /// + // Stop loading the page. + /// + /*--cef()--*/ + virtual void StopLoad() =0; + + /// + // Set focus for the browser window. If |enable| is true focus will be set to + // the window. Otherwise, focus will be removed. + /// + /*--cef()--*/ + virtual void SetFocus(bool enable) =0; + + /// + // Retrieve the window handle for this browser. + /// + /*--cef()--*/ + virtual CefWindowHandle GetWindowHandle() =0; + + /// + // Retrieve the window handle of the browser that opened this browser. Will + // return NULL for non-popup windows. This method can be used in combination + // with custom handling of modal windows. + /// + /*--cef()--*/ + virtual CefWindowHandle GetOpenerWindowHandle() =0; + + /// + // Returns the globally unique identifier for this browser. + /// + /*--cef()--*/ + virtual int GetIdentifier() =0; + + /// + // Returns true if the window is a popup window. + /// + /*--cef()--*/ + virtual bool IsPopup() =0; + + // Returns true if a document has been loaded in the browser. + /*--cef()--*/ + virtual bool HasDocument() =0; + + /// + // Returns the client for this browser. + /// + /*--cef()--*/ + virtual CefRefPtr GetClient() =0; + + /// + // Returns the main (top-level) frame for the browser window. + /// + /*--cef()--*/ + virtual CefRefPtr GetMainFrame() =0; + + /// + // Returns the focused frame for the browser window. This method should only + // be called on the UI thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusedFrame() =0; + + /// + // Returns the frame with the specified name, or NULL if not found. This + // method should only be called on the UI thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame(const CefString& name) =0; + + /// + // Returns the names of all existing frames. This method should only be called + // on the UI thread. + /// + /*--cef()--*/ + virtual void GetFrameNames(std::vector& names) =0; + + /// + // Search for |searchText|. |identifier| can be used to have multiple searches + // running simultaniously. |forward| indicates whether to search forward or + // backward within the page. |matchCase| indicates whether the search should + // be case-sensitive. |findNext| indicates whether this is the first request + // or a follow-up. + /// + /*--cef()--*/ + virtual void Find(int identifier, const CefString& searchText, + bool forward, bool matchCase, bool findNext) =0; + + /// + // Cancel all searches that are currently going on. + /// + /*--cef()--*/ + virtual void StopFinding(bool clearSelection) =0; + + /// + // Get the current zoom level. The default zoom level is 0.0. This method can + // only be called on the UI thread. + /// + /*--cef()--*/ + virtual double GetZoomLevel() =0; + + /// + // Change the zoom level to the specified value. Specify 0.0 to reset the + // zoom level. The change will be applied asynchronously on the UI thread. + /// + /*--cef()--*/ + virtual void SetZoomLevel(double zoomLevel) =0; + + /// + // Clear the back/forward browsing history. + /// + /*--cef()--*/ + virtual void ClearHistory() =0; + + /// + // Open developer tools in its own window. + /// + /*--cef()--*/ + virtual void ShowDevTools() =0; + + /// + // Explicitly close the developer tools window if one exists for this browser + // instance. + /// + /*--cef()--*/ + virtual void CloseDevTools() =0; + + /// + // Returns true if window rendering is disabled. + /// + /*--cef()--*/ + virtual bool IsWindowRenderingDisabled() =0; + + /// + // Get the size of the specified element. This method should only be called on + // the UI thread. + /// + /*--cef()--*/ + virtual bool GetSize(PaintElementType type, int& width, int& height) =0; + + /// + // Set the size of the specified element. This method is only used when window + // rendering is disabled. + /// + /*--cef()--*/ + virtual void SetSize(PaintElementType type, int width, int height) =0; + + /// + // Returns true if a popup is currently visible. This method should only be + // called on the UI thread. + /// + /*--cef()--*/ + virtual bool IsPopupVisible() =0; + + /// + // Hide the currently visible popup, if any. + /// + /*--cef()--*/ + virtual void HidePopup() =0; + + /// + // Invalidate the |dirtyRect| region of the view. This method is only used + // when window rendering is disabled and will result in a call to + // HandlePaint(). + /// + /*--cef()--*/ + virtual void Invalidate(const CefRect& dirtyRect) =0; + + /// + // Get the raw image data contained in the specified element without + // performing validation. The specified |width| and |height| dimensions must + // match the current element size. On Windows |buffer| must be width*height*4 + // bytes in size and represents a BGRA image with an upper-left origin. This + // method should only be called on the UI thread. + /// + /*--cef()--*/ + virtual bool GetImage(PaintElementType type, int width, int height, + void* buffer) =0; + + /// + // Send a key event to the browser. + /// + /*--cef()--*/ + virtual void SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, + int modifiers) =0; + + /// + // Send a mouse click event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. + /// + /*--cef()--*/ + virtual void SendMouseClickEvent(int x, int y, MouseButtonType type, + bool mouseUp, int clickCount) =0; + + /// + // Send a mouse move event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. + /// + /*--cef()--*/ + virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) =0; + + /// + // Send a mouse wheel event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. The |deltaX| and |deltaY| + // values represent the movement delta in the X and Y directions respectively. + /// + /*--cef()--*/ + virtual void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) =0; + + /// + // Send a focus event to the browser. + /// + /*--cef()--*/ + virtual void SendFocusEvent(bool setFocus) =0; + + /// + // Send a capture lost event to the browser. + /// + /*--cef()--*/ + virtual void SendCaptureLostEvent() =0; +}; + +#endif // CEF_INCLUDE_CEF_BROWSER_H_ diff --git a/cefpython/cef1/include/cef_client.h b/cefpython/cef1/include/cef_client.h new file mode 100644 index 00000000..0a93a3c1 --- /dev/null +++ b/cefpython/cef1/include/cef_client.h @@ -0,0 +1,196 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_CLIENT_H_ +#define CEF_INCLUDE_CEF_CLIENT_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_display_handler.h" +#include "include/cef_drag_handler.h" +#include "include/cef_find_handler.h" +#include "include/cef_focus_handler.h" +#include "include/cef_geolocation_handler.h" +#include "include/cef_jsdialog_handler.h" +#include "include/cef_keyboard_handler.h" +#include "include/cef_life_span_handler.h" +#include "include/cef_load_handler.h" +#include "include/cef_menu_handler.h" +#include "include/cef_permission_handler.h" +#include "include/cef_print_handler.h" +#include "include/cef_render_handler.h" +#include "include/cef_request_handler.h" +#include "include/cef_v8context_handler.h" +#include "include/cef_zoom_handler.h" + +/// +// Implement this interface to provide handler implementations. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefClient : public virtual CefBase { + public: + /// + // Return the handler for browser life span events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLifeSpanHandler() { + return NULL; + } + + /// + // Return the handler for browser load status events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLoadHandler() { + return NULL; + } + + /// + // Return the handler for browser request events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequestHandler() { + return NULL; + } + + /// + // Return the handler for browser display state events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDisplayHandler() { + return NULL; + } + + /// + // Return the handler for focus events. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusHandler() { + return NULL; + } + + /// + // Return the handler for keyboard events. + /// + /*--cef()--*/ + virtual CefRefPtr GetKeyboardHandler() { + return NULL; + } + + /// + // Return the handler for context menu events. + /// + /*--cef()--*/ + virtual CefRefPtr GetMenuHandler() { + return NULL; + } + + /// + // Return the handler for browser permission events. + /// + /*--cef()--*/ + virtual CefRefPtr GetPermissionHandler() { + return NULL; + } + + /// + // Return the handler for printing events. + /// + /*--cef()--*/ + virtual CefRefPtr GetPrintHandler() { + return NULL; + } + + /// + // Return the handler for find result events. + /// + /*--cef()--*/ + virtual CefRefPtr GetFindHandler() { + return NULL; + } + + /// + // Return the handler for JavaScript dialog events. + /// + /*--cef()--*/ + virtual CefRefPtr GetJSDialogHandler() { + return NULL; + } + + /// + // Return the handler for V8 context events. + /// + /*--cef()--*/ + virtual CefRefPtr GetV8ContextHandler() { + return NULL; + } + + /// + // Return the handler for off-screen rendering events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRenderHandler() { + return NULL; + } + + /// + // Return the handler for drag events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDragHandler() { + return NULL; + } + + /// + // Return the handler for geolocation permissions requests. If no handler is + // provided geolocation access will be denied by default. + /// + /*--cef()--*/ + virtual CefRefPtr GetGeolocationHandler() { + return NULL; + } + + /// + // Return the handler for zoom events. If no handler is provided the default + // zoom behavior will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetZoomHandler() { + return NULL; + } +}; + +#endif // CEF_INCLUDE_CEF_CLIENT_H_ diff --git a/cefpython/cef1/include/cef_command_line.h b/cefpython/cef1/include/cef_command_line.h new file mode 100644 index 00000000..a698187e --- /dev/null +++ b/cefpython/cef1/include/cef_command_line.h @@ -0,0 +1,160 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_COMMAND_LINE_H_ +#define CEF_INCLUDE_CEF_COMMAND_LINE_H_ +#pragma once + +#include "include/cef_base.h" +#include +#include + +/// +// Class used to create and/or parse command line arguments. Arguments with +// '--', '-' and, on Windows, '/' prefixes are considered switches. Switches +// will always precede any arguments without switch prefixes. Switches can +// optionally have a value specified using the '=' delimiter (e.g. +// "-switch=value"). An argument of "--" will terminate switch parsing with all +// subsequent tokens, regardless of prefix, being interpreted as non-switch +// arguments. Switch names are considered case-insensitive. This class can be +// used before CefInitialize() is called. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefCommandLine : public virtual CefBase { + public: + typedef std::vector ArgumentList; + typedef std::map SwitchMap; + + /// + // Create a new CefCommandLine instance. + /// + /*--cef(revision_check)--*/ + static CefRefPtr CreateCommandLine(); + + /// + // Initialize the command line with the specified |argc| and |argv| values. + // The first argument must be the name of the program. This method is only + // supported on non-Windows platforms. + /// + /*--cef()--*/ + virtual void InitFromArgv(int argc, const char* const* argv) =0; + + /// + // Initialize the command line with the string returned by calling + // GetCommandLineW(). This method is only supported on Windows. + /// + /*--cef()--*/ + virtual void InitFromString(const CefString& command_line) =0; + + /// + // Constructs and returns the represented command line string. Use this method + // cautiously because quoting behavior is unclear. + /// + /*--cef()--*/ + virtual CefString GetCommandLineString() =0; + + /// + // Get the program part of the command line string (the first item). + /// + /*--cef()--*/ + virtual CefString GetProgram() =0; + + /// + // Set the program part of the command line string (the first item). + /// + /*--cef()--*/ + virtual void SetProgram(const CefString& program) =0; + + /// + // Returns true if the command line has switches. + /// + /*--cef()--*/ + virtual bool HasSwitches() =0; + + /// + // Returns true if the command line contains the given switch. + /// + /*--cef()--*/ + virtual bool HasSwitch(const CefString& name) =0; + + /// + // Returns the value associated with the given switch. If the switch has no + // value or isn't present this method returns the empty string. + /// + /*--cef()--*/ + virtual CefString GetSwitchValue(const CefString& name) =0; + + /// + // Returns the map of switch names and values. If a switch has no value an + // empty string is returned. + /// + /*--cef()--*/ + virtual void GetSwitches(SwitchMap& switches) =0; + + /// + // Add a switch to the end of the command line. If the switch has no value + // pass an empty value string. + /// + /*--cef()--*/ + virtual void AppendSwitch(const CefString& name) =0; + + /// + // Add a switch with the specified value to the end of the command line. + /// + /*--cef()--*/ + virtual void AppendSwitchWithValue(const CefString& name, + const CefString& value) =0; + + /// + // True if there are remaining command line arguments. + /// + /*--cef()--*/ + virtual bool HasArguments() =0; + + /// + // Get the remaining command line arguments. + /// + /*--cef()--*/ + virtual void GetArguments(ArgumentList& arguments) =0; + + /// + // Add an argument to the end of the command line. + /// + /*--cef()--*/ + virtual void AppendArgument(const CefString& argument) =0; +}; + +#endif // CEF_INCLUDE_CEF_COMMAND_LINE_H_ diff --git a/cefpython/cef1/include/cef_content_filter.h b/cefpython/cef1/include/cef_content_filter.h new file mode 100644 index 00000000..af5cf175 --- /dev/null +++ b/cefpython/cef1/include/cef_content_filter.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_CONTENT_FILTER_H_ +#define CEF_INCLUDE_CEF_CONTENT_FILTER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Interface to implement for filtering response content. The methods of this +// class will always be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefContentFilter : public virtual CefBase { + public: + /// + // Set |substitute_data| to the replacement for the data in |data| if data + // should be modified. + /// + /*--cef()--*/ + virtual void ProcessData(const void* data, int data_size, + CefRefPtr& substitute_data) {} + + /// + // Called when there is no more data to be processed. It is expected that + // whatever data was retained in the last ProcessData() call, it should be + // returned now by setting |remainder| if appropriate. + /// + /*--cef()--*/ + virtual void Drain(CefRefPtr& remainder) {} +}; + +#endif // CEF_INCLUDE_CEF_CONTENT_FILTER_H_ diff --git a/cefpython/cef1/include/cef_cookie.h b/cefpython/cef1/include/cef_cookie.h new file mode 100644 index 00000000..d24325c3 --- /dev/null +++ b/cefpython/cef1/include/cef_cookie.h @@ -0,0 +1,147 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_COOKIE_H_ +#define CEF_INCLUDE_CEF_COOKIE_H_ +#pragma once + +#include "include/cef_base.h" +#include + +class CefCookieVisitor; + + +/// +// Class used for managing cookies. The methods of this class may be called on +// any thread unless otherwise indicated. +/// +/*--cef(source=library)--*/ +class CefCookieManager : public virtual CefBase { + public: + /// + // Returns the global cookie manager. By default data will be stored at + // CefSettings.cache_path if specified or in memory otherwise. + /// + /*--cef()--*/ + static CefRefPtr GetGlobalManager(); + + /// + // Creates a new cookie manager. If |path| is empty data will be stored in + // memory only. Returns NULL if creation fails. + /// + /*--cef(optional_param=path)--*/ + static CefRefPtr CreateManager(const CefString& path); + + /// + // Set the schemes supported by this manager. By default only "http" and + // "https" schemes are supported. Must be called before any cookies are + // accessed. + /// + /*--cef()--*/ + virtual void SetSupportedSchemes(const std::vector& schemes) =0; + + /// + // Visit all cookies. The returned cookies are ordered by longest path, then + // by earliest creation date. Returns false if cookies cannot be accessed. + /// + /*--cef()--*/ + virtual bool VisitAllCookies(CefRefPtr visitor) =0; + + /// + // Visit a subset of cookies. The results are filtered by the given url + // scheme, host, domain and path. If |includeHttpOnly| is true HTTP-only + // cookies will also be included in the results. The returned cookies are + // ordered by longest path, then by earliest creation date. Returns false if + // cookies cannot be accessed. + /// + /*--cef()--*/ + virtual bool VisitUrlCookies(const CefString& url, bool includeHttpOnly, + CefRefPtr visitor) =0; + + /// + // Sets a cookie given a valid URL and explicit user-provided cookie + // attributes. This function expects each attribute to be well-formed. It will + // check for disallowed characters (e.g. the ';' character is disallowed + // within the cookie value attribute) and will return false without setting + // the cookie if such characters are found. This method must be called on the + // IO thread. + /// + /*--cef()--*/ + virtual bool SetCookie(const CefString& url, const CefCookie& cookie) =0; + + /// + // Delete all cookies that match the specified parameters. If both |url| and + // values |cookie_name| are specified all host and domain cookies matching + // both will be deleted. If only |url| is specified all host cookies (but not + // domain cookies) irrespective of path will be deleted. If |url| is empty all + // cookies for all hosts and domains will be deleted. Returns false if a non- + // empty invalid URL is specified or if cookies cannot be accessed. This + // method must be called on the IO thread. + /// + /*--cef(optional_param=url,optional_param=cookie_name)--*/ + virtual bool DeleteCookies(const CefString& url, + const CefString& cookie_name) =0; + + /// + // Sets the directory path that will be used for storing cookie data. If + // |path| is empty data will be stored in memory only. Returns false if + // cookies cannot be accessed. + /// + /*--cef(optional_param=path)--*/ + virtual bool SetStoragePath(const CefString& path) =0; +}; + + +/// +// Interface to implement for visiting cookie values. The methods of this class +// will always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefCookieVisitor : public virtual CefBase { + public: + /// + // Method that will be called once for each cookie. |count| is the 0-based + // index for the current cookie. |total| is the total number of cookies. + // Set |deleteCookie| to true to delete the cookie currently being visited. + // Return false to stop visiting cookies. This method may never be called if + // no cookies are found. + /// + /*--cef()--*/ + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) =0; +}; + +#endif // CEF_INCLUDE_CEF_COOKIE_H_ diff --git a/cefpython/cef1/include/cef_display_handler.h b/cefpython/cef1/include/cef_display_handler.h new file mode 100644 index 00000000..1558da24 --- /dev/null +++ b/cefpython/cef1/include/cef_display_handler.h @@ -0,0 +1,124 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ +#define CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to browser display state. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDisplayHandler : public virtual CefBase { + public: + typedef cef_handler_statustype_t StatusType; + + /// + // Called when the navigation state has changed. + /// + /*--cef()--*/ + virtual void OnNavStateChange(CefRefPtr browser, + bool canGoBack, + bool canGoForward) {} + + /// + // Called when a frame's address has changed. + /// + /*--cef()--*/ + virtual void OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) {} + + /// + // Called when the size of the content area has changed. + /// + /*--cef()--*/ + virtual void OnContentsSizeChange(CefRefPtr browser, + CefRefPtr frame, + int width, + int height) {} + + /// + // Called when the page title changes. + /// + /*--cef(optional_param=title)--*/ + virtual void OnTitleChange(CefRefPtr browser, + const CefString& title) {} + + /// + // Called when the Favicon URL for a page changes. + /// + /*--cef()--*/ + virtual void OnFaviconURLChange(CefRefPtr browser, + const std::vector& icon_urls) {} + + /// + // Called when the browser is about to display a tooltip. |text| contains the + // text that will be displayed in the tooltip. To handle the display of the + // tooltip yourself return true. Otherwise, you can optionally modify |text| + // and then return false to allow the browser to display the tooltip. + /// + /*--cef(optional_param=text)--*/ + virtual bool OnTooltip(CefRefPtr browser, + CefString& text) { return false; } + + /// + // Called when the browser receives a status message. |text| contains the text + // that will be displayed in the status message and |type| indicates the + // status message type. + /// + /*--cef(optional_param=value)--*/ + virtual void OnStatusMessage(CefRefPtr browser, + const CefString& value, + StatusType type) {} + + /// + // Called to display a console message. Return true to stop the message from + // being output to the console. + /// + /*--cef(optional_param=message,optional_param=source)--*/ + virtual bool OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_dom.h b/cefpython/cef1/include/cef_dom.h new file mode 100644 index 00000000..b56050d8 --- /dev/null +++ b/cefpython/cef1/include/cef_dom.h @@ -0,0 +1,429 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DOM_H_ +#define CEF_INCLUDE_CEF_DOM_H_ +#pragma once + +#include "include/cef_base.h" +#include + +class CefDOMDocument; +class CefDOMEventListener; +class CefDOMNode; + +/// +// Interface to implement for visiting the DOM. The methods of this class will +// be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDOMVisitor : public virtual CefBase { + public: + /// + // Method executed for visiting the DOM. The document object passed to this + // method represents a snapshot of the DOM at the time this method is + // executed. DOM objects are only valid for the scope of this method. Do not + // keep references to or attempt to access any DOM objects outside the scope + // of this method. + /// + /*--cef()--*/ + virtual void Visit(CefRefPtr document) =0; +}; + + +/// +// Class used to represent a DOM document. The methods of this class should only +// be called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefDOMDocument : public virtual CefBase { + public: + typedef cef_dom_document_type_t Type; + + /// + // Returns the document type. + /// + /*--cef(default_retval=DOM_DOCUMENT_TYPE_UNKNOWN)--*/ + virtual Type GetType() =0; + + /// + // Returns the root document node. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the BODY node of an HTML document. + /// + /*--cef()--*/ + virtual CefRefPtr GetBody() =0; + + /// + // Returns the HEAD node of an HTML document. + /// + /*--cef()--*/ + virtual CefRefPtr GetHead() =0; + + /// + // Returns the title of an HTML document. + /// + /*--cef()--*/ + virtual CefString GetTitle() =0; + + /// + // Returns the document element with the specified ID value. + /// + /*--cef()--*/ + virtual CefRefPtr GetElementById(const CefString& id) =0; + + /// + // Returns the node that currently has keyboard focus. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusedNode() =0; + + /// + // Returns true if a portion of the document is selected. + /// + /*--cef()--*/ + virtual bool HasSelection() =0; + + /// + // Returns the selection start node. + /// + /*--cef()--*/ + virtual CefRefPtr GetSelectionStartNode() =0; + + /// + // Returns the selection offset within the start node. + /// + /*--cef()--*/ + virtual int GetSelectionStartOffset() =0; + + /// + // Returns the selection end node. + /// + /*--cef()--*/ + virtual CefRefPtr GetSelectionEndNode() =0; + + /// + // Returns the selection offset within the end node. + /// + /*--cef()--*/ + virtual int GetSelectionEndOffset() =0; + + /// + // Returns the contents of this selection as markup. + /// + /*--cef()--*/ + virtual CefString GetSelectionAsMarkup() =0; + + /// + // Returns the contents of this selection as text. + /// + /*--cef()--*/ + virtual CefString GetSelectionAsText() =0; + + /// + // Returns the base URL for the document. + /// + /*--cef()--*/ + virtual CefString GetBaseURL() =0; + + /// + // Returns a complete URL based on the document base URL and the specified + // partial URL. + /// + /*--cef()--*/ + virtual CefString GetCompleteURL(const CefString& partialURL) =0; +}; + + +/// +// Class used to represent a DOM node. The methods of this class should only be +// called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefDOMNode : public virtual CefBase { + public: + typedef std::map AttributeMap; + typedef cef_dom_node_type_t Type; + + /// + // Returns the type for this node. + /// + /*--cef(default_retval=DOM_NODE_TYPE_UNSUPPORTED)--*/ + virtual Type GetType() =0; + + /// + // Returns true if this is a text node. + /// + /*--cef()--*/ + virtual bool IsText() =0; + + /// + // Returns true if this is an element node. + /// + /*--cef()--*/ + virtual bool IsElement() =0; + + /// + // Returns true if this is a form control element node. + /// + /*--cef()--*/ + virtual bool IsFormControlElement() =0; + + /// + // Returns the type of this form control element node. + /// + /*--cef()--*/ + virtual CefString GetFormControlElementType() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Returns the name of this node. + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the value of this node. + /// + /*--cef()--*/ + virtual CefString GetValue() =0; + + /// + // Set the value of this node. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetValue(const CefString& value) =0; + + /// + // Returns the contents of this node as markup. + /// + /*--cef()--*/ + virtual CefString GetAsMarkup() =0; + + /// + // Returns the document associated with this node. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the parent node. + /// + /*--cef()--*/ + virtual CefRefPtr GetParent() =0; + + /// + // Returns the previous sibling node. + /// + /*--cef()--*/ + virtual CefRefPtr GetPreviousSibling() =0; + + /// + // Returns the next sibling node. + /// + /*--cef()--*/ + virtual CefRefPtr GetNextSibling() =0; + + /// + // Returns true if this node has child nodes. + /// + /*--cef()--*/ + virtual bool HasChildren() =0; + + /// + // Return the first child node. + /// + /*--cef()--*/ + virtual CefRefPtr GetFirstChild() =0; + + /// + // Returns the last child node. + /// + /*--cef()--*/ + virtual CefRefPtr GetLastChild() =0; + + /// + // Add an event listener to this node for the specified event type. If + // |useCapture| is true then this listener will be considered a capturing + // listener. Capturing listeners will recieve all events of the specified + // type before the events are dispatched to any other event targets beneath + // the current node in the tree. Events which are bubbling upwards through + // the tree will not trigger a capturing listener. Separate calls to this + // method can be used to register the same listener with and without capture. + // See WebCore/dom/EventNames.h for the list of supported event types. + /// + /*--cef()--*/ + virtual void AddEventListener(const CefString& eventType, + CefRefPtr listener, + bool useCapture) =0; + + + // The following methods are valid only for element nodes. + + /// + // Returns the tag name of this element. + /// + /*--cef()--*/ + virtual CefString GetElementTagName() =0; + + /// + // Returns true if this element has attributes. + /// + /*--cef()--*/ + virtual bool HasElementAttributes() =0; + + /// + // Returns true if this element has an attribute named |attrName|. + /// + /*--cef()--*/ + virtual bool HasElementAttribute(const CefString& attrName) =0; + + /// + // Returns the element attribute named |attrName|. + /// + /*--cef()--*/ + virtual CefString GetElementAttribute(const CefString& attrName) =0; + + /// + // Returns a map of all element attributes. + /// + /*--cef()--*/ + virtual void GetElementAttributes(AttributeMap& attrMap) =0; + + /// + // Set the value for the element attribute named |attrName|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool SetElementAttribute(const CefString& attrName, + const CefString& value) =0; + + /// + // Returns the inner text of the element. + /// + /*--cef()--*/ + virtual CefString GetElementInnerText() =0; +}; + + +/// +// Class used to represent a DOM event. The methods of this class should only +// be called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefDOMEvent : public virtual CefBase { + public: + typedef cef_dom_event_category_t Category; + typedef cef_dom_event_phase_t Phase; + + /// + // Returns the event type. + /// + /*--cef()--*/ + virtual CefString GetType() =0; + + /// + // Returns the event category. + /// + /*--cef(default_retval=DOM_EVENT_CATEGORY_UNKNOWN)--*/ + virtual Category GetCategory() =0; + + /// + // Returns the event processing phase. + /// + /*--cef(default_retval=DOM_EVENT_PHASE_UNKNOWN)--*/ + virtual Phase GetPhase() =0; + + /// + // Returns true if the event can bubble up the tree. + /// + /*--cef()--*/ + virtual bool CanBubble() =0; + + /// + // Returns true if the event can be canceled. + /// + /*--cef()--*/ + virtual bool CanCancel() =0; + + /// + // Returns the document associated with this event. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the target of the event. + /// + /*--cef()--*/ + virtual CefRefPtr GetTarget() =0; + + /// + // Returns the current target of the event. + /// + /*--cef()--*/ + virtual CefRefPtr GetCurrentTarget() =0; +}; + + +/// +// Interface to implement for handling DOM events. The methods of this class +// will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDOMEventListener : public virtual CefBase { + public: + /// + // Called when an event is received. The event object passed to this method + // contains a snapshot of the DOM at the time this method is executed. DOM + // objects are only valid for the scope of this method. Do not keep references + // to or attempt to access any DOM objects outside the scope of this method. + /// + /*--cef()--*/ + virtual void HandleEvent(CefRefPtr event) =0; +}; + +#endif // CEF_INCLUDE_CEF_DOM_H_ diff --git a/cefpython/cef1/include/cef_download_handler.h b/cefpython/cef1/include/cef_download_handler.h new file mode 100644 index 00000000..8fd20944 --- /dev/null +++ b/cefpython/cef1/include/cef_download_handler.h @@ -0,0 +1,65 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ +#define CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Class used to handle file downloads. The methods of this class will always be +// called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDownloadHandler : public virtual CefBase { + public: + /// + // A portion of the file contents have been received. This method will be + // called multiple times until the download is complete. Return |true| to + // continue receiving data and |false| to cancel. + /// + /*--cef()--*/ + virtual bool ReceivedData(void* data, int data_size) =0; + + /// + // The download is complete. + /// + /*--cef()--*/ + virtual void Complete() =0; +}; + +#endif // CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_drag_data.h b/cefpython/cef1/include/cef_drag_data.h new file mode 100644 index 00000000..54400cdd --- /dev/null +++ b/cefpython/cef1/include/cef_drag_data.h @@ -0,0 +1,120 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_DATA_H_ +#define CEF_INCLUDE_CEF_DRAG_DATA_H_ +#pragma once + +#include "include/cef_base.h" +#include + +/// +// Class used to represent drag data. The methods of this class may be called +// on any thread. +/// +/*--cef(source=library)--*/ +class CefDragData : public virtual CefBase { + public: + /// + // Returns true if the drag data is a link. + /// + /*--cef()--*/ + virtual bool IsLink() =0; + + /// + // Returns true if the drag data is a text or html fragment. + /// + /*--cef()--*/ + virtual bool IsFragment() =0; + + /// + // Returns true if the drag data is a file. + /// + /*--cef()--*/ + virtual bool IsFile() =0; + + /// + // Return the link URL that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkURL() =0; + + /// + // Return the title associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkTitle() =0; + + /// + // Return the metadata, if any, associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkMetadata() =0; + + /// + // Return the plain text fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentText() =0; + + /// + // Return the text/html fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentHtml() =0; + + /// + // Return the base URL that the fragment came from. This value is used for + // resolving relative URLs and may be empty. + /// + /*--cef()--*/ + virtual CefString GetFragmentBaseURL() =0; + + /// + // Return the name of the file being dragged out of the browser window. + /// + /*--cef()--*/ + virtual CefString GetFileName() =0; + + /// + // Retrieve the list of file names that are being dragged into the browser + // window. + /// + /*--cef()--*/ + virtual bool GetFileNames(std::vector& names) =0; +}; + +#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_ diff --git a/cefpython/cef1/include/cef_drag_handler.h b/cefpython/cef1/include/cef_drag_handler.h new file mode 100644 index 00000000..79d90e57 --- /dev/null +++ b/cefpython/cef1/include/cef_drag_handler.h @@ -0,0 +1,77 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#define CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_drag_data.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to dragging. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDragHandler : public virtual CefBase { + public: + typedef cef_drag_operations_mask_t DragOperationsMask; + + /// + // Called when the browser window initiates a drag event. |dragData| + // contains the drag event data and |mask| represents the type of drag + // operation. Return false for default drag handling behavior or true to + // cancel the drag event. + /// + /*--cef()--*/ + virtual bool OnDragStart(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { return false; } + + /// + // Called when an external drag event enters the browser window. |dragData| + // contains the drag event data and |mask| represents the type of drag + // operation. Return false for default drag handling behavior or true to + // cancel the drag event. + /// + /*--cef()--*/ + virtual bool OnDragEnter(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_DRAG_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_find_handler.h b/cefpython/cef1/include/cef_find_handler.h new file mode 100644 index 00000000..bead6fee --- /dev/null +++ b/cefpython/cef1/include/cef_find_handler.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_FIND_HANDLER_H_ +#define CEF_INCLUDE_CEF_FIND_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to find results. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefFindHandler : public virtual CefBase { + public: + /// + // Called to report find results returned by CefBrowser::Find(). |identifer| + // is the identifier passed to CefBrowser::Find(), |count| is the number of + // matches currently identified, |selectionRect| is the location of where the + // match was found (in window coordinates), |activeMatchOrdinal| is the + // current position in the search results, and |finalUpdate| is true if this + // is the last find notification. + /// + /*--cef()--*/ + virtual void OnFindResult(CefRefPtr browser, + int identifier, + int count, + const CefRect& selectionRect, + int activeMatchOrdinal, + bool finalUpdate) {} +}; + +#endif // CEF_INCLUDE_CEF_FIND_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_focus_handler.h b/cefpython/cef1/include/cef_focus_handler.h new file mode 100644 index 00000000..a45b6f52 --- /dev/null +++ b/cefpython/cef1/include/cef_focus_handler.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ +#define CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_dom.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to focus. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefFocusHandler : public virtual CefBase { + public: + typedef cef_handler_focus_source_t FocusSource; + + /// + // Called when the browser component is about to loose focus. For instance, if + // focus was on the last HTML element and the user pressed the TAB key. |next| + // will be true if the browser is giving focus to the next component and false + // if the browser is giving focus to the previous component. + /// + /*--cef()--*/ + virtual void OnTakeFocus(CefRefPtr browser, + bool next) {} + + /// + // Called when the browser component is requesting focus. |source| indicates + // where the focus request is originating from. Return false to allow the + // focus to be set or true to cancel setting the focus. + /// + /*--cef()--*/ + virtual bool OnSetFocus(CefRefPtr browser, + FocusSource source) { return false; } + + /// + // Called when a new node in the the browser gets focus. The |node| value may + // be empty if no specific node has gained focus. The node object passed to + // this method represents a snapshot of the DOM at the time this method is + // executed. DOM objects are only valid for the scope of this method. Do not + // keep references to or attempt to access any DOM objects outside the scope + // of this method. + /// + /*--cef(optional_param=frame,optional_param=node)--*/ + virtual void OnFocusedNodeChanged(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr node) {} +}; + +#endif // CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_frame.h b/cefpython/cef1/include/cef_frame.h new file mode 100644 index 00000000..f0ac6ef7 --- /dev/null +++ b/cefpython/cef1/include/cef_frame.h @@ -0,0 +1,220 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_FRAME_H_ +#define CEF_INCLUDE_CEF_FRAME_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_dom.h" +#include "include/cef_request.h" +#include "include/cef_stream.h" + +class CefBrowser; +class CefV8Context; + +/// +// Class used to represent a frame in the browser window. The methods of this +// class may be called on any thread unless otherwise indicated in the comments. +/// +/*--cef(source=library)--*/ +class CefFrame : public virtual CefBase { + public: + /// + // Execute undo in this frame. + /// + /*--cef()--*/ + virtual void Undo() =0; + /// + // Execute redo in this frame. + /// + /*--cef()--*/ + virtual void Redo() =0; + /// + // Execute cut in this frame. + /// + /*--cef()--*/ + virtual void Cut() =0; + /// + // Execute copy in this frame. + /// + /*--cef()--*/ + virtual void Copy() =0; + /// + // Execute paste in this frame. + /// + /*--cef()--*/ + virtual void Paste() =0; + /// + // Execute delete in this frame. + /// + /*--cef(capi_name=del)--*/ + virtual void Delete() =0; + /// + // Execute select all in this frame. + /// + /*--cef()--*/ + virtual void SelectAll() =0; + + /// + // Execute printing in the this frame. The user will be prompted with the + // print dialog appropriate to the operating system. + /// + /*--cef()--*/ + virtual void Print() =0; + + /// + // Save this frame's HTML source to a temporary file and open it in the + // default text viewing application. + /// + /*--cef()--*/ + virtual void ViewSource() =0; + + /// + // Returns this frame's HTML source as a string. This method should only be + // called on the UI thread. + /// + /*--cef()--*/ + virtual CefString GetSource() =0; + + /// + // Returns this frame's display text as a string. This method should only be + // called on the UI thread. + /// + /*--cef()--*/ + virtual CefString GetText() =0; + + /// + // Load the request represented by the |request| object. + /// + /*--cef()--*/ + virtual void LoadRequest(CefRefPtr request) =0; + + /// + // Load the specified |url|. + /// + /*--cef()--*/ + virtual void LoadURL(const CefString& url) =0; + + /// + // Load the contents of |string_val| with the optional dummy target |url|. + /// + /*--cef()--*/ + virtual void LoadString(const CefString& string_val, + const CefString& url) =0; + + /// + // Load the contents of |stream| with the optional dummy target |url|. + /// + /*--cef()--*/ + virtual void LoadStream(CefRefPtr stream, + const CefString& url) =0; + + /// + // Execute a string of JavaScript code in this frame. The |script_url| + // parameter is the URL where the script in question can be found, if any. + // The renderer may request this URL to show the developer the source of the + // error. The |start_line| parameter is the base line number to use for error + // reporting. + /// + /*--cef(optional_param=scriptUrl)--*/ + virtual void ExecuteJavaScript(const CefString& jsCode, + const CefString& scriptUrl, + int startLine) =0; + + /// + // Returns true if this is the main (top-level) frame. + /// + /*--cef()--*/ + virtual bool IsMain() =0; + + /// + // Returns true if this is the focused frame. This method should only be + // called on the UI thread. + /// + /*--cef()--*/ + virtual bool IsFocused() =0; + + /// + // Returns the name for this frame. If the frame has an assigned name (for + // example, set via the iframe "name" attribute) then that value will be + // returned. Otherwise a unique name will be constructed based on the frame + // parent hierarchy. The main (top-level) frame will always have an empty name + // value. + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the globally unique identifier for this frame. + /// + /*--cef()--*/ + virtual int64 GetIdentifier() =0; + + /// + // Returns the parent of this frame or NULL if this is the main (top-level) + // frame. This method should only be called on the UI thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetParent() =0; + + /// + // Returns the URL currently loaded in this frame. + /// + /*--cef()--*/ + virtual CefString GetURL() =0; + + /// + // Returns the browser that this frame belongs to. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowser() =0; + + /// + // Visit the DOM document. + /// + /*--cef()--*/ + virtual void VisitDOM(CefRefPtr visitor) =0; + + /// + // Get the V8 context associated with the frame. This method should only be + // called on the UI thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetV8Context() =0; +}; + +#endif // CEF_INCLUDE_CEF_FRAME_H_ diff --git a/cefpython/cef1/include/cef_geolocation.h b/cefpython/cef1/include/cef_geolocation.h new file mode 100644 index 00000000..69c08779 --- /dev/null +++ b/cefpython/cef1/include/cef_geolocation.h @@ -0,0 +1,66 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_GEOLOCATION_H_ +#define CEF_INCLUDE_CEF_GEOLOCATION_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Implement this interface to receive geolocation updates. The methods of this +// class will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefGetGeolocationCallback : public virtual CefBase { + public: + /// + // Called with the 'best available' location information or, if the location + // update failed, with error information. + /// + /*--cef()--*/ + virtual void OnLocationUpdate(const CefGeoposition& position) =0; +}; + +/// +// Request a one-time geolocation update. This function bypasses any user +// permission checks so should only be used by code that is allowed to access +// location information. +/// +/*--cef()--*/ +bool CefGetGeolocation(CefRefPtr callback); + +#endif // CEF_INCLUDE_CEF_GEOLOCATION_H_ diff --git a/cefpython/cef1/include/cef_geolocation_handler.h b/cefpython/cef1/include/cef_geolocation_handler.h new file mode 100644 index 00000000..4b732b48 --- /dev/null +++ b/cefpython/cef1/include/cef_geolocation_handler.h @@ -0,0 +1,94 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ +#define CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Callback interface used for asynchronous continuation of geolocation +// permission requests. +/// +/*--cef(source=library)--*/ +class CefGeolocationCallback : public virtual CefBase { + public: + /// + // Call to allow or deny geolocation access. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(bool allow) =0; +}; + + +/// +// Implement this interface to handle events related to geolocation permission +// requests. The methods of this class will be called on the browser process UI +// thread. +/// +/*--cef(source=client)--*/ +class CefGeolocationHandler : public virtual CefBase { + public: + /// + // Called when a page requests permission to access geolocation information. + // |requesting_url| is the URL requesting permission and |request_id| is the + // unique ID for the permission request. Call CefGeolocationCallback::Continue + // to allow or deny the permission request. + /// + /*--cef()--*/ + virtual void OnRequestGeolocationPermission( + CefRefPtr browser, + const CefString& requesting_url, + int request_id, + CefRefPtr callback) { + } + + /// + // Called when a geolocation access request is canceled. |requesting_url| is + // the URL that originally requested permission and |request_id| is the unique + // ID for the permission request. + /// + /*--cef()--*/ + virtual void OnCancelGeolocationPermission( + CefRefPtr browser, + const CefString& requesting_url, + int request_id) { + } +}; + +#endif // CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_jsdialog_handler.h b/cefpython/cef1/include/cef_jsdialog_handler.h new file mode 100644 index 00000000..d3067f3c --- /dev/null +++ b/cefpython/cef1/include/cef_jsdialog_handler.h @@ -0,0 +1,87 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ +#define CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to JavaScript dialogs. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefJSDialogHandler : public virtual CefBase { + public: + /// + // Called to run a JavaScript alert message. Return false to display the + // default alert or true if you displayed a custom alert. + /// + /*--cef(optional_param=message)--*/ + virtual bool OnJSAlert(CefRefPtr browser, + CefRefPtr frame, + const CefString& message) { return false; } + + /// + // Called to run a JavaScript confirm request. Return false to display the + // default alert or true if you displayed a custom alert. If you handled the + // alert set |retval| to true if the user accepted the confirmation. + /// + /*--cef(optional_param=message)--*/ + virtual bool OnJSConfirm(CefRefPtr browser, + CefRefPtr frame, + const CefString& message, + bool& retval) { return false; } + + /// + // Called to run a JavaScript prompt request. Return false to display the + // default prompt or true if you displayed a custom prompt. If you handled + // the prompt set |retval| to true if the user accepted the prompt and request + // and |result| to the resulting value. + /// + /*--cef(optional_param=message,optional_param=defaultValue)--*/ + virtual bool OnJSPrompt(CefRefPtr browser, + CefRefPtr frame, + const CefString& message, + const CefString& defaultValue, + bool& retval, + CefString& result) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_keyboard_handler.h b/cefpython/cef1/include/cef_keyboard_handler.h new file mode 100644 index 00000000..a8133e91 --- /dev/null +++ b/cefpython/cef1/include/cef_keyboard_handler.h @@ -0,0 +1,76 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ +#define CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to keyboard input. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefKeyboardHandler : public virtual CefBase { + public: + typedef cef_handler_keyevent_type_t KeyEventType; + + /// + // Called when the browser component receives a keyboard event. This method + // is called both before the event is passed to the renderer and after + // JavaScript in the page has had a chance to handle the event. |type| is the + // type of keyboard event, |code| is the windows scan-code for the event, + // |modifiers| is a set of bit- flags describing any pressed modifier keys and + // |isSystemKey| is true if Windows considers this a 'system key' message (see + // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx). If + // |isAfterJavaScript| is true then JavaScript in the page has had a chance + // to handle the event and has chosen not to. Only RAWKEYDOWN, KEYDOWN and + // CHAR events will be sent with |isAfterJavaScript| set to true. Return + // true if the keyboard event was handled or false to allow continued handling + // of the event by the renderer. + /// + /*--cef()--*/ + virtual bool OnKeyEvent(CefRefPtr browser, + KeyEventType type, + int code, + int modifiers, + bool isSystemKey, + bool isAfterJavaScript) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_life_span_handler.h b/cefpython/cef1/include/cef_life_span_handler.h new file mode 100644 index 00000000..907d755a --- /dev/null +++ b/cefpython/cef1/include/cef_life_span_handler.h @@ -0,0 +1,105 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ +#define CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +class CefClient; + +/// +// Implement this interface to handle events related to browser life span. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefLifeSpanHandler : public virtual CefBase { + public: + /// + // Called before a new popup window is created. The |parentBrowser| parameter + // will point to the parent browser window. The |popupFeatures| parameter will + // contain information about the style of popup window requested. Return false + // to have the framework create the new popup window based on the parameters + // in |windowInfo|. Return true to cancel creation of the popup window. By + // default, a newly created popup window will have the same client and + // settings as the parent window. To change the client for the new window + // modify the object that |client| points to. To change the settings for the + // new window modify the |settings| structure. + /// + /*--cef(optional_param=url)--*/ + virtual bool OnBeforePopup(CefRefPtr parentBrowser, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + CefRefPtr& client, + CefBrowserSettings& settings) { return false; } + + /// + // Called after a new window is created. + /// + /*--cef()--*/ + virtual void OnAfterCreated(CefRefPtr browser) {} + + /// + // Called when a modal window is about to display and the modal loop should + // begin running. Return false to use the default modal loop implementation or + // true to use a custom implementation. + /// + /*--cef()--*/ + virtual bool RunModal(CefRefPtr browser) { return false; } + + /// + // Called when a window has recieved a request to close. Return false to + // proceed with the window close or true to cancel the window close. If this + // is a modal window and a custom modal loop implementation was provided in + // RunModal() this callback should be used to restore the opener window to a + // usable state. + /// + /*--cef()--*/ + virtual bool DoClose(CefRefPtr browser) { return false; } + + /// + // Called just before a window is closed. If this is a modal window and a + // custom modal loop implementation was provided in RunModal() this callback + // should be used to exit the custom modal loop. + /// + /*--cef()--*/ + virtual void OnBeforeClose(CefRefPtr browser) {} +}; + +#endif // CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_load_handler.h b/cefpython/cef1/include/cef_load_handler.h new file mode 100644 index 00000000..bfa01df2 --- /dev/null +++ b/cefpython/cef1/include/cef_load_handler.h @@ -0,0 +1,94 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_LOAD_HANDLER_H_ +#define CEF_INCLUDE_CEF_LOAD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to browser load status. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefLoadHandler : public virtual CefBase { + public: + typedef cef_handler_errorcode_t ErrorCode; + + /// + // Called when the browser begins loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // may not be called for a particular frame if the load request for that frame + // fails. + /// + /*--cef()--*/ + virtual void OnLoadStart(CefRefPtr browser, + CefRefPtr frame) {} + + /// + // Called when the browser is done loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // will always be called for all frames irrespective of whether the request + // completes successfully. + /// + /*--cef()--*/ + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) {} + + /// + // Called when the browser fails to load a resource. |errorCode| is the error + // code number and |failedUrl| is the URL that failed to load. To provide + // custom error text assign the text to |errorText| and return true. + // Otherwise, return false for the default error text. See + // net\base\net_error_list.h for complete descriptions of the error codes. + /// + /*--cef()--*/ + virtual bool OnLoadError(CefRefPtr browser, + CefRefPtr frame, + ErrorCode errorCode, + const CefString& failedUrl, + CefString& errorText) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_LOAD_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_menu_handler.h b/cefpython/cef1/include/cef_menu_handler.h new file mode 100644 index 00000000..81fe115b --- /dev/null +++ b/cefpython/cef1/include/cef_menu_handler.h @@ -0,0 +1,80 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_MENU_HANDLER_H_ +#define CEF_INCLUDE_CEF_MENU_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to browser context menus. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefMenuHandler : public virtual CefBase { + public: + typedef cef_menu_id_t MenuId; + + /// + // Called before a context menu is displayed. Return false to display the + // default context menu or true to cancel the display. + /// + /*--cef()--*/ + virtual bool OnBeforeMenu(CefRefPtr browser, + const CefMenuInfo& menuInfo) { return false; } + + /// + // Called to optionally override the default text for a context menu item. + // |label| contains the default text and may be modified to substitute + // alternate text. + /// + /*--cef()--*/ + virtual void GetMenuLabel(CefRefPtr browser, + MenuId menuId, + CefString& label) {} + + /// + // Called when an option is selected from the default context menu. Return + // false to execute the default action or true to cancel the action. + /// + /*--cef()--*/ + virtual bool OnMenuAction(CefRefPtr browser, + MenuId menuId) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_MENU_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_nplugin.h b/cefpython/cef1/include/cef_nplugin.h new file mode 100644 index 00000000..4b16fe91 --- /dev/null +++ b/cefpython/cef1/include/cef_nplugin.h @@ -0,0 +1,119 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_CEF_NPLUGIN_H_ +#define CEF_INCLUDE_CEF_NPLUGIN_H_ +#pragma once + +#include "internal/cef_nplugin_types.h" + +/// +// Netscape plugins are normally built at separate DLLs that are loaded by the +// browser when needed. This interface supports the creation of plugins that +// are an embedded component of the application. Embedded plugins built using +// this interface use the same Netscape Plugin API as DLL-based plugins. +// See https://developer.mozilla.org/En/Gecko_Plugin_API_Reference for complete +// documentation on how to use the Netscape Plugin API. +// +// This class provides attribute information and entry point functions for a +// plugin. +/// +class CefPluginInfo : public cef_plugin_info_t { + public: + CefPluginInfo() { + Init(); + } + virtual ~CefPluginInfo() { + Reset(); + } + + CefPluginInfo(const CefPluginInfo& r) { // NOLINT(runtime/explicit) + Init(); + *this = r; + } + CefPluginInfo(const cef_plugin_info_t& r) { // NOLINT(runtime/explicit) + Init(); + *this = r; + } + + void Reset() { + cef_string_clear(&unique_name); + cef_string_clear(&display_name); + cef_string_clear(&version); + cef_string_clear(&description); + cef_string_clear(&mime_types); + cef_string_clear(&file_extensions); + cef_string_clear(&type_descriptions); + Init(); + } + + void Attach(const cef_plugin_info_t& r) { + Reset(); + *static_cast(this) = r; + } + + void Detach() { + Init(); + } + + CefPluginInfo& operator=(const CefPluginInfo& r) { + return operator=(static_cast(r)); + } + + CefPluginInfo& operator=(const cef_plugin_info_t& r) { + cef_string_copy(r.unique_name.str, r.unique_name.length, &unique_name); + cef_string_copy(r.display_name.str, r.display_name.length, &display_name); + cef_string_copy(r.version.str, r.version.length, &version); + cef_string_copy(r.description.str, r.description.length, &description); + cef_string_copy(r.mime_types.str, r.mime_types.length, &mime_types); + cef_string_copy(r.file_extensions.str, r.file_extensions.length, + &file_extensions); + cef_string_copy(r.type_descriptions.str, r.type_descriptions.length, + &type_descriptions); +#if !defined(OS_POSIX) || defined(OS_MACOSX) + np_getentrypoints = r.np_getentrypoints; +#endif + np_initialize = r.np_initialize; + np_shutdown = r.np_shutdown; + return *this; + } + + protected: + void Init() { + memset(static_cast(this), 0, sizeof(cef_plugin_info_t)); + } +}; + +/// +// Register a plugin with the system. +/// +bool CefRegisterPlugin(const CefPluginInfo& plugin_info); + +#endif // CEF_INCLUDE_CEF_NPLUGIN_H_ diff --git a/cefpython/cef1/include/cef_origin_whitelist.h b/cefpython/cef1/include/cef_origin_whitelist.h new file mode 100644 index 00000000..fd434460 --- /dev/null +++ b/cefpython/cef1/include/cef_origin_whitelist.h @@ -0,0 +1,102 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ +#define CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ +#pragma once + +#include "include/cef_base.h" + + +/// +// Add an entry to the cross-origin access whitelist. +// +// The same-origin policy restricts how scripts hosted from different origins +// (scheme + domain + port) can communicate. By default, scripts can only access +// resources with the same origin. Scripts hosted on the HTTP and HTTPS schemes +// (but no other schemes) can use the "Access-Control-Allow-Origin" header to +// allow cross-origin requests. For example, https://source.example.com can make +// XMLHttpRequest requests on http://target.example.com if the +// http://target.example.com request returns an "Access-Control-Allow-Origin: +// https://source.example.com" response header. +// +// Scripts in separate frames or iframes and hosted from the same protocol and +// domain suffix can execute cross-origin JavaScript if both pages set the +// document.domain value to the same domain suffix. For example, +// scheme://foo.example.com and scheme://bar.example.com can communicate using +// JavaScript if both domains set document.domain="example.com". +// +// This method is used to allow access to origins that would otherwise violate +// the same-origin policy. Scripts hosted underneath the fully qualified +// |source_origin| URL (like http://www.example.com) will be allowed access to +// all resources hosted on the specified |target_protocol| and |target_domain|. +// If |target_domain| is non-empty and |allow_target_subdomains| if false only +// exact domain matches will be allowed. If |target_domain| is non-empty and +// |allow_target_subdomains| is true sub-domain matches will be allowed. If +// |target_domain| is empty and |allow_target_subdomains| if true all domains +// and IP addresses will be allowed. +// +// This method cannot be used to bypass the restrictions on local or display +// isolated schemes. See the comments on CefRegisterCustomScheme for more +// information. +// +// This function may be called on any thread. Returns false if |source_origin| +// is invalid or the whitelist cannot be accessed. +/// +/*--cef(optional_param=target_domain)--*/ +bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin, + const CefString& target_protocol, + const CefString& target_domain, + bool allow_target_subdomains); + +/// +// Remove an entry from the cross-origin access whitelist. Returns false if +// |source_origin| is invalid or the whitelist cannot be accessed. +/// +/*--cef(optional_param=target_domain)--*/ +bool CefRemoveCrossOriginWhitelistEntry(const CefString& source_origin, + const CefString& target_protocol, + const CefString& target_domain, + bool allow_target_subdomains); + +/// +// Remove all entries from the cross-origin access whitelist. Returns false if +// the whitelist cannot be accessed. +/// +/*--cef()--*/ +bool CefClearCrossOriginWhitelist(); + +#endif // CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ diff --git a/cefpython/cef1/include/cef_permission_handler.h b/cefpython/cef1/include/cef_permission_handler.h new file mode 100644 index 00000000..aea8e46b --- /dev/null +++ b/cefpython/cef1/include/cef_permission_handler.h @@ -0,0 +1,64 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_PERMISSION_HANDLER_H_ +#define CEF_INCLUDE_CEF_PERMISSION_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to browser permissions. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefPermissionHandler : public virtual CefBase { + public: + /// + // Called on the UI thread before a script extension is loaded. + // Return false to let the extension load normally. + /// + /*--cef()--*/ + virtual bool OnBeforeScriptExtensionLoad(CefRefPtr browser, + CefRefPtr frame, + const CefString& extensionName) { + return false; + } +}; + +#endif // CEF_INCLUDE_CEF_PERMISSION_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_print_handler.h b/cefpython/cef1/include/cef_print_handler.h new file mode 100644 index 00000000..d47fbf63 --- /dev/null +++ b/cefpython/cef1/include/cef_print_handler.h @@ -0,0 +1,91 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_PRINT_HANDLER_H_ +#define CEF_INCLUDE_CEF_PRINT_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to printing. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefPrintHandler : public virtual CefBase { + public: + /// + // Called to allow customization of standard print options before the print + // dialog is displayed. |printOptions| allows specification of paper size, + // orientation and margins. Note that the specified margins may be adjusted if + // they are outside the range supported by the printer. All units are in + // inches. Return false to display the default print options or true to + // display the modified |printOptions|. + /// + /*--cef()--*/ + virtual bool GetPrintOptions(CefRefPtr browser, + CefPrintOptions& printOptions) { return false; } + + /// + // Called to format print headers and footers. |printInfo| contains platform- + // specific information about the printer context. |url| is the URL if the + // currently printing page, |title| is the title of the currently printing + // page, |currentPage| is the current page number and |maxPages| is the total + // number of pages. Six default header locations are provided by the + // implementation: top left, top center, top right, bottom left, bottom center + // and bottom right. To use one of these default locations just assign a + // string to the appropriate variable. To draw the header and footer yourself + // return true. Otherwise, populate the approprate variables and return false. + /// + /*--cef()--*/ + virtual bool GetPrintHeaderFooter(CefRefPtr browser, + CefRefPtr frame, + const CefPrintInfo& printInfo, + const CefString& url, + const CefString& title, + int currentPage, + int maxPages, + CefString& topLeft, + CefString& topCenter, + CefString& topRight, + CefString& bottomLeft, + CefString& bottomCenter, + CefString& bottomRight) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_PRINT_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_proxy_handler.h b/cefpython/cef1/include/cef_proxy_handler.h new file mode 100644 index 00000000..d40c67d7 --- /dev/null +++ b/cefpython/cef1/include/cef_proxy_handler.h @@ -0,0 +1,57 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_PROXY_HANDLER_H_ +#define CEF_INCLUDE_CEF_PROXY_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Implement this interface to handle proxy resolution events. +/// +/*--cef(source=client)--*/ +class CefProxyHandler : public virtual CefBase { + public: + /// + // Called to retrieve proxy information for the specified |url|. + /// + /*--cef()--*/ + virtual void GetProxyForUrl(const CefString& url, + CefProxyInfo& proxy_info) {} +}; + +#endif // CEF_INCLUDE_CEF_PROXY_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_render_handler.h b/cefpython/cef1/include/cef_render_handler.h new file mode 100644 index 00000000..643fbbf5 --- /dev/null +++ b/cefpython/cef1/include/cef_render_handler.h @@ -0,0 +1,121 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RENDER_HANDLER_H_ +#define CEF_INCLUDE_CEF_RENDER_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include + +/// +// Implement this interface to handle events when window rendering is disabled. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefRenderHandler : public virtual CefBase { + public: + typedef cef_paint_element_type_t PaintElementType; + typedef std::vector RectList; + + /// + // Called to retrieve the view rectangle which is relative to screen + // coordinates. Return true if the rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetViewRect(CefRefPtr browser, + CefRect& rect) { return false; } + + /// + // Called to retrieve the simulated screen rectangle. Return true if the + // rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetScreenRect(CefRefPtr browser, + CefRect& rect) { return false; } + + /// + // Called to retrieve the translation from view coordinates to actual screen + // coordinates. Return true if the screen coordinates were provided. + /// + /*--cef()--*/ + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { return false; } + + /// + // Called when the browser wants to show or hide the popup widget. The popup + // should be shown if |show| is true and hidden if |show| is false. + /// + /*--cef()--*/ + virtual void OnPopupShow(CefRefPtr browser, + bool show) {} + + /// + // Called when the browser wants to move or resize the popup widget. |rect| + // contains the new location and size. + /// + /*--cef()--*/ + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) {} + + /// + // Called when an element should be painted. |type| indicates whether the + // element is the view or the popup widget. |buffer| contains the pixel data + // for the whole image. |dirtyRects| contains the set of rectangles that need + // to be repainted. On Windows |buffer| will be width*height*4 bytes in size + // and represents a BGRA image with an upper-left origin. The + // CefBrowserSettings.animation_frame_rate value controls the rate at which + // this method is called. + /// + /*--cef()--*/ + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer) {} + + /// + // Called when the browser window's cursor has changed. + /// + /*--cef()--*/ + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) {} +}; + +#endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_request.h b/cefpython/cef1/include/cef_request.h new file mode 100644 index 00000000..95ade79b --- /dev/null +++ b/cefpython/cef1/include/cef_request.h @@ -0,0 +1,255 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_H_ +#define CEF_INCLUDE_CEF_REQUEST_H_ +#pragma once + +#include "include/cef_base.h" +#include +#include + +class CefPostData; +class CefPostDataElement; + +/// +// Class used to represent a web request. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library)--*/ +class CefRequest : public virtual CefBase { + public: + typedef std::multimap HeaderMap; + typedef cef_weburlrequest_flags_t RequestFlags; + + /// + // Create a new CefRequest object. + /// + /*--cef()--*/ + static CefRefPtr CreateRequest(); + + /// + // Get the fully qualified URL. + /// + /*--cef()--*/ + virtual CefString GetURL() =0; + /// + // Set the fully qualified URL. + /// + /*--cef()--*/ + virtual void SetURL(const CefString& url) =0; + + /// + // Get the request method type. The value will default to POST if post data + // is provided and GET otherwise. + /// + /*--cef()--*/ + virtual CefString GetMethod() =0; + /// + // Set the request method type. + /// + /*--cef()--*/ + virtual void SetMethod(const CefString& method) =0; + + /// + // Get the post data. + /// + /*--cef()--*/ + virtual CefRefPtr GetPostData() =0; + /// + // Set the post data. + /// + /*--cef()--*/ + virtual void SetPostData(CefRefPtr postData) =0; + + /// + // Get the header values. + /// + /*--cef()--*/ + virtual void GetHeaderMap(HeaderMap& headerMap) =0; + /// + // Set the header values. + /// + /*--cef()--*/ + virtual void SetHeaderMap(const HeaderMap& headerMap) =0; + + /// + // Set all values at one time. + /// + /*--cef(optional_param=postData)--*/ + virtual void Set(const CefString& url, + const CefString& method, + CefRefPtr postData, + const HeaderMap& headerMap) =0; + + /// + // Get the flags used in combination with CefWebURLRequest. + /// + /*--cef(default_retval=WUR_FLAG_NONE)--*/ + virtual RequestFlags GetFlags() =0; + /// + // Set the flags used in combination with CefWebURLRequest. + /// + /*--cef()--*/ + virtual void SetFlags(RequestFlags flags) =0; + + /// + // Set the URL to the first party for cookies used in combination with + // CefWebURLRequest. + /// + /*--cef()--*/ + virtual CefString GetFirstPartyForCookies() =0; + /// + // Get the URL to the first party for cookies used in combination with + // CefWebURLRequest. + /// + /*--cef()--*/ + virtual void SetFirstPartyForCookies(const CefString& url) =0; +}; + + +/// +// Class used to represent post data for a web request. The methods of this +// class may be called on any thread. +/// +/*--cef(source=library)--*/ +class CefPostData : public virtual CefBase { + public: + typedef std::vector > ElementVector; + + /// + // Create a new CefPostData object. + /// + /*--cef()--*/ + static CefRefPtr CreatePostData(); + + /// + // Returns the number of existing post data elements. + /// + /*--cef()--*/ + virtual size_t GetElementCount() =0; + + /// + // Retrieve the post data elements. + /// + /*--cef(count_func=elements:GetElementCount)--*/ + virtual void GetElements(ElementVector& elements) =0; + + /// + // Remove the specified post data element. Returns true if the removal + // succeeds. + /// + /*--cef()--*/ + virtual bool RemoveElement(CefRefPtr element) =0; + + /// + // Add the specified post data element. Returns true if the add succeeds. + /// + /*--cef()--*/ + virtual bool AddElement(CefRefPtr element) =0; + + /// + // Remove all existing post data elements. + /// + /*--cef()--*/ + virtual void RemoveElements() =0; +}; + + +/// +// Class used to represent a single element in the request post data. The +// methods of this class may be called on any thread. +/// +/*--cef(source=library)--*/ +class CefPostDataElement : public virtual CefBase { + public: + /// + // Post data elements may represent either bytes or files. + /// + typedef cef_postdataelement_type_t Type; + + /// + // Create a new CefPostDataElement object. + /// + /*--cef()--*/ + static CefRefPtr CreatePostDataElement(); + + /// + // Remove all contents from the post data element. + /// + /*--cef()--*/ + virtual void SetToEmpty() =0; + + /// + // The post data element will represent a file. + /// + /*--cef()--*/ + virtual void SetToFile(const CefString& fileName) =0; + + /// + // The post data element will represent bytes. The bytes passed + // in will be copied. + /// + /*--cef()--*/ + virtual void SetToBytes(size_t size, const void* bytes) =0; + + /// + // Return the type of this post data element. + /// + /*--cef(default_retval=PDE_TYPE_EMPTY)--*/ + virtual Type GetType() =0; + + /// + // Return the file name. + /// + /*--cef()--*/ + virtual CefString GetFile() =0; + + /// + // Return the number of bytes. + /// + /*--cef()--*/ + virtual size_t GetBytesCount() =0; + + /// + // Read up to |size| bytes into |bytes| and return the number of bytes + // actually read. + /// + /*--cef()--*/ + virtual size_t GetBytes(size_t size, void* bytes) =0; +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_H_ diff --git a/cefpython/cef1/include/cef_request_handler.h b/cefpython/cef1/include/cef_request_handler.h new file mode 100644 index 00000000..a9c7f1d6 --- /dev/null +++ b/cefpython/cef1/include/cef_request_handler.h @@ -0,0 +1,171 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ +#define CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_cookie.h" +#include "include/cef_download_handler.h" +#include "include/cef_frame.h" +#include "include/cef_content_filter.h" +#include "include/cef_response.h" +#include "include/cef_request.h" +#include "include/cef_stream.h" + +/// +// Implement this interface to handle events related to browser requests. The +// methods of this class will be called on the thread indicated. +/// +/*--cef(source=client)--*/ +class CefRequestHandler : public virtual CefBase { + public: + typedef cef_handler_navtype_t NavType; + + /// + // Called on the UI thread before browser navigation. Return true to cancel + // the navigation or false to allow the navigation to proceed. + /// + /*--cef()--*/ + virtual bool OnBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + NavType navType, + bool isRedirect) { return false; } + + /// + // Called on the IO thread before a resource is loaded. To allow the resource + // to load normally return false. To redirect the resource to a new url + // populate the |redirectUrl| value and return false. To specify data for the + // resource return a CefStream object in |resourceStream|, use the |response| + // object to set mime type, HTTP status code and optional header values, and + // return false. To cancel loading of the resource return true. Any + // modifications to |request| will be observed. If the URL in |request| is + // changed and |redirectUrl| is also set, the URL in |request| will be used. + /// + /*--cef()--*/ + virtual bool OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr request, + CefString& redirectUrl, + CefRefPtr& resourceStream, + CefRefPtr response, + int loadFlags) { return false; } + + /// + // Called on the IO thread when a resource load is redirected. The |old_url| + // parameter will contain the old URL. The |new_url| parameter will contain + // the new URL and can be changed if desired. + /// + /*--cef()--*/ + virtual void OnResourceRedirect(CefRefPtr browser, + const CefString& old_url, + CefString& new_url) {} + + /// + // Called on the UI thread after a response to the resource request is + // received. Set |filter| if response content needs to be monitored and/or + // modified as it arrives. + /// + /*--cef()--*/ + virtual void OnResourceResponse(CefRefPtr browser, + const CefString& url, + CefRefPtr response, + CefRefPtr& filter) {} + + /// + // Called on the IO thread to handle requests for URLs with an unknown + // protocol component. Return true to indicate that the request should + // succeed because it was handled externally. Set |allowOSExecution| to true + // and return false to attempt execution via the registered OS protocol + // handler, if any. If false is returned and either |allow_os_execution| + // is false or OS protocol handler execution fails then the request will fail + // with an error condition. + // SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED + // ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. + /// + /*--cef()--*/ + virtual bool OnProtocolExecution(CefRefPtr browser, + const CefString& url, + bool& allowOSExecution) { return false; } + + /// + // Called on the UI thread when a server indicates via the + // 'Content-Disposition' header that a response represents a file to download. + // |mimeType| is the mime type for the download, |fileName| is the suggested + // target file name and |contentLength| is either the value of the + // 'Content-Size' header or -1 if no size was provided. Set |handler| to the + // CefDownloadHandler instance that will recieve the file contents. Return + // true to download the file or false to cancel the file download. + /// + /*--cef(optional_param=mimeType)--*/ + virtual bool GetDownloadHandler(CefRefPtr browser, + const CefString& mimeType, + const CefString& fileName, + int64 contentLength, + CefRefPtr& handler) + { return false; } + + /// + // Called on the IO thread when the browser needs credentials from the user. + // |isProxy| indicates whether the host is a proxy server. |host| contains the + // hostname and port number. Set |username| and |password| and return + // true to handle the request. Return false to cancel the request. + /// + /*--cef(optional_param=realm)--*/ + virtual bool GetAuthCredentials(CefRefPtr browser, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefString& username, + CefString& password) { return false; } + + /// + // Called on the IO thread to retrieve the cookie manager. |main_url| is the + // URL of the top-level frame. Cookies managers can be unique per browser or + // shared across multiple browsers. The global cookie manager will be used if + // this method returns NULL. + /// + /*--cef()--*/ + virtual CefRefPtr GetCookieManager( + CefRefPtr browser, + const CefString& main_url) { return NULL; } +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_resource_bundle_handler.h b/cefpython/cef1/include/cef_resource_bundle_handler.h new file mode 100644 index 00000000..e7a37d1b --- /dev/null +++ b/cefpython/cef1/include/cef_resource_bundle_handler.h @@ -0,0 +1,82 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ +#define CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Class used to implement a custom resource bundle interface. The methods of +// this class may be called on multiple threads. +/// +/*--cef(source=client)--*/ +class CefResourceBundleHandler : public virtual CefBase { + public: + /// + // Called to retrieve a localized translation for the string specified by + // |message_id|. To provide the translation set |string| to the translation + // string and return true. To use the default translation return false. + // + // WARNING: Be cautious when implementing this method. ID values are auto- + // generated when CEF is built and may change between versions. Existing ID + // values can be discovered by searching for *_strings.h in the + // "obj/global_intermediate" build output directory. + /// + /*--cef()--*/ + virtual bool GetLocalizedString(int message_id, + CefString& string) =0; + + /// + // Called to retrieve data for the resource specified by |resource_id|. To + // provide the resource data set |data| and |data_size| to the data pointer + // and size respectively and return true. To use the default resource data + // return false. The resource data will not be copied and must remain resident + // in memory. + // + // WARNING: Be cautious when implementing this method. ID values are auto- + // generated when CEF is built and may change between versions. Existing ID + // values can be discovered by searching for *_resources.h in the + // "obj/global_intermediate" build output directory. + /// + /*--cef()--*/ + virtual bool GetDataResource(int resource_id, + void*& data, + size_t& data_size) =0; +}; + +#endif // CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_response.h b/cefpython/cef1/include/cef_response.h new file mode 100644 index 00000000..5448cd71 --- /dev/null +++ b/cefpython/cef1/include/cef_response.h @@ -0,0 +1,104 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESPONSE_H_ +#define CEF_INCLUDE_CEF_RESPONSE_H_ +#pragma once + +#include "include/cef_base.h" +#include + +/// +// Class used to represent a web response. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library)--*/ +class CefResponse : public virtual CefBase { + public: + typedef std::multimap HeaderMap; + + /// + // Get the response status code. + /// + /*--cef()--*/ + virtual int GetStatus() =0; + /// + // Set the response status code. + /// + /*--cef()--*/ + virtual void SetStatus(int status) = 0; + + /// + // Get the response status text. + /// + /*--cef()--*/ + virtual CefString GetStatusText() =0; + /// + // Set the response status text. + /// + /*--cef()--*/ + virtual void SetStatusText(const CefString& statusText) = 0; + + /// + // Get the response mime type. + /// + /*--cef()--*/ + virtual CefString GetMimeType() = 0; + /// + // Set the response mime type. + /// + /*--cef()--*/ + virtual void SetMimeType(const CefString& mimeType) = 0; + + /// + // Get the value for the specified response header field. + /// + /*--cef()--*/ + virtual CefString GetHeader(const CefString& name) =0; + + /// + // Get all response header fields. + /// + /*--cef()--*/ + virtual void GetHeaderMap(HeaderMap& headerMap) =0; + /// + // Set all response header fields. + /// + /*--cef()--*/ + virtual void SetHeaderMap(const HeaderMap& headerMap) =0; +}; + +#endif // CEF_INCLUDE_CEF_RESPONSE_H_ diff --git a/cefpython/cef1/include/cef_runnable.h b/cefpython/cef1/include/cef_runnable.h new file mode 100644 index 00000000..826ddaa4 --- /dev/null +++ b/cefpython/cef1/include/cef_runnable.h @@ -0,0 +1,346 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2011 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The contents of this file are a modified extract of base/task.h + +#ifndef CEF_INCLUDE_CEF_RUNNABLE_H_ +#define CEF_INCLUDE_CEF_RUNNABLE_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_task.h" +#ifdef BUILDING_CEF_SHARED +#include "base/tuple.h" +#else +#include "internal/cef_tuple.h" +#endif + +// CefRunnableMethodTraits ----------------------------------------------------- +// +// This traits-class is used by CefRunnableMethod to manage the lifetime of the +// callee object. By default, it is assumed that the callee supports AddRef +// and Release methods. A particular class can specialize this template to +// define other lifetime management. For example, if the callee is known to +// live longer than the CefRunnableMethod object, then a CefRunnableMethodTraits +// struct could be defined with empty RetainCallee and ReleaseCallee methods. +// +// The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way +// for declaring a CefRunnableMethodTraits that disables refcounting. + +template +struct CefRunnableMethodTraits { + CefRunnableMethodTraits() { + } + + ~CefRunnableMethodTraits() { + } + + void RetainCallee(T* obj) { +#ifndef NDEBUG + // Catch NewCefRunnableMethod being called in an object's constructor. + // This isn't safe since the method can be invoked before the constructor + // completes, causing the object to be deleted. + obj->AddRef(); + obj->Release(); +#endif + obj->AddRef(); + } + + void ReleaseCallee(T* obj) { + obj->Release(); + } +}; + +// Convenience macro for declaring a CefRunnableMethodTraits that disables +// refcounting of a class. This is useful if you know that the callee +// will outlive the CefRunnableMethod object and thus do not need the ref +// counts. +// +// The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the +// global namespace scope. Example: +// +// namespace foo { +// class Bar { +// ... +// }; +// } // namespace foo +// +// DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar); +// +// This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the +// class. +#define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \ + template <> \ + struct CefRunnableMethodTraits { \ + void RetainCallee(TypeName* manager) {} \ + void ReleaseCallee(TypeName* manager) {} \ + } + +// CefRunnableMethod and CefRunnableFunction ---------------------------------- +// +// CefRunnable methods are a type of task that call a function on an object +// when they are run. We implement both an object and a set of +// NewCefRunnableMethod and NewCefRunnableFunction functions for convenience. +// These functions are overloaded and will infer the template types, +// simplifying calling code. +// +// The template definitions all use the following names: +// T - the class type of the object you're supplying +// this is not needed for the Static version of the call +// Method/Function - the signature of a pointer to the method or function you +// want to call +// Param - the parameter(s) to the method, possibly packed as a Tuple +// A - the first parameter (if any) to the method +// B - the second parameter (if any) to the method +// +// Put these all together and you get an object that can call a method whose +// signature is: +// R T::MyFunction([A[, B]]) +// +// Usage: +// CefPostTask(TID_UI, NewCefRunnableMethod(object, &Object::method[, a[, b]]) +// CefPostTask(TID_UI, NewCefRunnableFunction(&function[, a[, b]]) + +// CefRunnableMethod and NewCefRunnableMethod implementation ------------------ + +template +class CefRunnableMethod : public CefTask { + public: + CefRunnableMethod(T* obj, Method meth, const Params& params) + : obj_(obj), meth_(meth), params_(params) { + traits_.RetainCallee(obj_); + } + + ~CefRunnableMethod() { + T* obj = obj_; + obj_ = NULL; + if (obj) + traits_.ReleaseCallee(obj); + } + + virtual void Execute(CefThreadId threadId) { + if (obj_) + DispatchToMethod(obj_, meth_, params_); + } + + private: + T* obj_; + Method meth_; + Params params_; + CefRunnableMethodTraits traits_; + + IMPLEMENT_REFCOUNTING(CefRunnableMethod); +}; + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method) { + return new CefRunnableMethod(object, method, MakeTuple()); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b, + c)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b, + c, + d)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, d, + e)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, d, + e, f)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, + d, e, f, + g)); +} + +// CefRunnableFunction and NewCefRunnableFunction implementation -------------- + +template +class CefRunnableFunction : public CefTask { + public: + CefRunnableFunction(Function function, const Params& params) + : function_(function), params_(params) { + } + + ~CefRunnableFunction() { + } + + virtual void Execute(CefThreadId threadId) { + if (function_) + DispatchToFunction(function_, params_); + } + + private: + Function function_; + Params params_; + + IMPLEMENT_REFCOUNTING(CefRunnableFunction); +}; + +template +inline CefRefPtr NewCefRunnableFunction(Function function) { + return new CefRunnableFunction(function, MakeTuple()); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a) { + return new CefRunnableFunction >(function, MakeTuple(a)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b) { + return new CefRunnableFunction >(function, + MakeTuple(a, b)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, + c)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, + c, + d)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, c, d, e)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, c, d, e, f)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g) { + return new CefRunnableFunction >( + function, MakeTuple(a, b, c, d, e, f, g)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g, const H& h) { + return new CefRunnableFunction >( + function, MakeTuple(a, b, c, d, e, f, g, h)); +} + +#endif // CEF_INCLUDE_CEF_RUNNABLE_H_ diff --git a/cefpython/cef1/include/cef_scheme.h b/cefpython/cef1/include/cef_scheme.h new file mode 100644 index 00000000..97786590 --- /dev/null +++ b/cefpython/cef1/include/cef_scheme.h @@ -0,0 +1,231 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_SCHEME_H_ +#define CEF_INCLUDE_CEF_SCHEME_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_response.h" +#include "include/cef_request.h" + +class CefSchemeHandler; +class CefSchemeHandlerFactory; + +/// +// Register a scheme handler factory for the specified |scheme_name| and +// optional |domain_name|. An empty |domain_name| value for a standard scheme +// will cause the factory to match all domain names. The |domain_name| value +// will be ignored for non-standard schemes. If |scheme_name| is a built-in +// scheme and no handler is returned by |factory| then the built-in scheme +// handler factory will be called. If |scheme_name| is a custom scheme the +// CefRegisterCustomScheme() function should be called for that scheme. +// This function may be called multiple times to change or remove the factory +// that matches the specified |scheme_name| and optional |domain_name|. +// Returns false if an error occurs. This function may be called on any thread. +/// +/*--cef(optional_param=domain_name,optional_param=factory)--*/ +bool CefRegisterSchemeHandlerFactory(const CefString& scheme_name, + const CefString& domain_name, + CefRefPtr factory); + +/// +// Clear all registered scheme handler factories. Returns false on error. This +// function may be called on any thread. +/// +/*--cef()--*/ +bool CefClearSchemeHandlerFactories(); + + +/// +// Class that manages custom scheme registrations. +/// +/*--cef(source=library)--*/ +class CefSchemeRegistrar : public virtual CefBase { + public: + /// + // Register a custom scheme. This method should not be called for the built-in + // HTTP, HTTPS, FILE, FTP, ABOUT and DATA schemes. + // + // If |is_standard| is true the scheme will be treated as a standard scheme. + // Standard schemes are subject to URL canonicalization and parsing rules as + // defined in the Common Internet Scheme Syntax RFC 1738 Section 3.1 available + // at http://www.ietf.org/rfc/rfc1738.txt + // + // In particular, the syntax for standard scheme URLs must be of the form: + //
+  //  [scheme]://[username]:[password]@[host]:[port]/[url-path]
+  // 
+ // Standard scheme URLs must have a host component that is a fully qualified + // domain name as defined in Section 3.5 of RFC 1034 [13] and Section 2.1 of + // RFC 1123. These URLs will be canonicalized to "scheme://host/path" in the + // simplest case and "scheme://username:password@host:port/path" in the most + // explicit case. For example, "scheme:host/path" and "scheme:///host/path" + // will both be canonicalized to "scheme://host/path". The origin of a + // standard scheme URL is the combination of scheme, host and port (i.e., + // "scheme://host:port" in the most explicit case). + // + // For non-standard scheme URLs only the "scheme:" component is parsed and + // canonicalized. The remainder of the URL will be passed to the handler + // as-is. For example, "scheme:///some%20text" will remain the same. + // Non-standard scheme URLs cannot be used as a target for form submission. + // + // If |is_local| is true the scheme will be treated as local (i.e., with the + // same security rules as those applied to "file" URLs). Normal pages cannot + // link to or access local URLs. Also, by default, local URLs can only perform + // XMLHttpRequest calls to the same URL (origin + path) that originated the + // request. To allow XMLHttpRequest calls from a local URL to other URLs with + // the same origin set the CefSettings.file_access_from_file_urls_allowed + // value to true. To allow XMLHttpRequest calls from a local URL to all + // origins set the CefSettings.universal_access_from_file_urls_allowed value + // to true. + // + // If |is_display_isolated| is true the scheme will be treated as display- + // isolated. This means that pages cannot display these URLs unless they are + // from the same scheme. For example, pages in another origin cannot create + // iframes or hyperlinks to URLs with this scheme. + // + // This function may be called on any thread. It should only be called once + // per unique |scheme_name| value. If |scheme_name| is already registered or + // if an error occurs this method will return false. + /// + /*--cef()--*/ + virtual bool AddCustomScheme(const CefString& scheme_name, + bool is_standard, + bool is_local, + bool is_display_isolated) =0; +}; + + +/// +// Class that creates CefSchemeHandler instances. The methods of this class will +// always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefSchemeHandlerFactory : public virtual CefBase { + public: + /// + // Return a new scheme handler instance to handle the request. |browser| will + // be the browser window that initiated the request. If the request was + // initiated using the CefWebURLRequest API |browser| will be NULL. The + // |request| object passed to this method will not contain cookie data. + /// + /*--cef(optional_param=browser)--*/ + virtual CefRefPtr Create(CefRefPtr browser, + const CefString& scheme_name, + CefRefPtr request) =0; +}; + +/// +// Class used to facilitate asynchronous responses to custom scheme handler +// requests. The methods of this class may be called on any thread. +/// +/*--cef(source=library)--*/ +class CefSchemeHandlerCallback : public virtual CefBase { + public: + /// + // Notify that header information is now available for retrieval. + /// + /*--cef()--*/ + virtual void HeadersAvailable() =0; + + /// + // Notify that response data is now available for reading. + /// + /*--cef()--*/ + virtual void BytesAvailable() =0; + + /// + // Cancel processing of the request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +/// +// Class used to implement a custom scheme handler interface. The methods of +// this class will always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefSchemeHandler : public virtual CefBase { + public: + /// + // Begin processing the request. To handle the request return true and call + // HeadersAvailable() once the response header information is available + // (HeadersAvailable() can also be called from inside this method if header + // information is available immediately). To cancel the request return false. + /// + /*--cef()--*/ + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) =0; + + /// + // Retrieve response header information. If the response length is not known + // set |response_length| to -1 and ReadResponse() will be called until it + // returns false. If the response length is known set |response_length| + // to a positive value and ReadResponse() will be called until it returns + // false or the specified number of bytes have been read. Use the |response| + // object to set the mime type, http status code and other optional header + // values. To redirect the request to a new URL set |redirectUrl| to the new + // URL. + /// + /*--cef()--*/ + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) =0; + + /// + // Read response data. If data is available immediately copy up to + // |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of + // bytes copied, and return true. To read the data at a later time set + // |bytes_read| to 0, return true and call BytesAvailable() when the data is + // available. To indicate response completion return false. + /// + /*--cef()--*/ + virtual bool ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) =0; + + /// + // Request processing has been canceled. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +#endif // CEF_INCLUDE_CEF_SCHEME_H_ diff --git a/cefpython/cef1/include/cef_stream.h b/cefpython/cef1/include/cef_stream.h new file mode 100644 index 00000000..8daae170 --- /dev/null +++ b/cefpython/cef1/include/cef_stream.h @@ -0,0 +1,210 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_STREAM_H_ +#define CEF_INCLUDE_CEF_STREAM_H_ + +#include "include/cef_base.h" + +/// +// Interface the client can implement to provide a custom stream reader. The +// methods of this class may be called on any thread. +/// +/*--cef(source=client)--*/ +class CefReadHandler : public virtual CefBase { + public: + /// + // Read raw binary data. + /// + /*--cef()--*/ + virtual size_t Read(void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Return zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Return non-zero if at end of file. + /// + /*--cef()--*/ + virtual int Eof() =0; +}; + + +/// +// Class used to read data from a stream. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library)--*/ +class CefStreamReader : public virtual CefBase { + public: + /// + // Create a new CefStreamReader object from a file. + /// + /*--cef()--*/ + static CefRefPtr CreateForFile(const CefString& fileName); + /// + // Create a new CefStreamReader object from data. + /// + /*--cef()--*/ + static CefRefPtr CreateForData(void* data, size_t size); + /// + // Create a new CefStreamReader object from a custom handler. + /// + /*--cef()--*/ + static CefRefPtr CreateForHandler( + CefRefPtr handler); + + /// + // Read raw binary data. + /// + /*--cef()--*/ + virtual size_t Read(void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Returns zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Return non-zero if at end of file. + /// + /*--cef()--*/ + virtual int Eof() =0; +}; + + +/// +// Interface the client can implement to provide a custom stream writer. The +// methods of this class may be called on any thread. +/// +/*--cef(source=client)--*/ +class CefWriteHandler : public virtual CefBase { + public: + /// + // Write raw binary data. + /// + /*--cef()--*/ + virtual size_t Write(const void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Return zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Flush the stream. + /// + /*--cef()--*/ + virtual int Flush() =0; +}; + + +/// +// Class used to write data to a stream. The methods of this class may be called +// on any thread. +/// +/*--cef(source=library)--*/ +class CefStreamWriter : public virtual CefBase { + public: + /// + // Create a new CefStreamWriter object for a file. + /// + /*--cef()--*/ + static CefRefPtr CreateForFile(const CefString& fileName); + /// + // Create a new CefStreamWriter object for a custom handler. + /// + /*--cef()--*/ + static CefRefPtr CreateForHandler( + CefRefPtr handler); + + /// + // Write raw binary data. + /// + /*--cef()--*/ + virtual size_t Write(const void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Returns zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Flush the stream. + /// + /*--cef()--*/ + virtual int Flush() =0; +}; + +#endif // CEF_INCLUDE_CEF_STREAM_H_ diff --git a/cefpython/cef1/include/cef_task.h b/cefpython/cef1/include/cef_task.h new file mode 100644 index 00000000..86550f6a --- /dev/null +++ b/cefpython/cef1/include/cef_task.h @@ -0,0 +1,89 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_TASK_H_ +#define CEF_INCLUDE_CEF_TASK_H_ + +#include "include/cef_base.h" + +class CefTask; + +typedef cef_thread_id_t CefThreadId; + +/// +// CEF maintains multiple internal threads that are used for handling different +// types of tasks. The UI thread creates the browser window and is used for all +// interaction with the WebKit rendering engine and V8 JavaScript engine (The +// UI thread will be the same as the main application thread if CefInitialize() +// is called with a CefSettings.multi_threaded_message_loop value of false.) The +// IO thread is used for handling schema and network requests. The FILE thread +// is used for the application cache and other miscellaneous activities. This +// function will return true if called on the specified thread. +/// +/*--cef()--*/ +bool CefCurrentlyOn(CefThreadId threadId); + +/// +// Post a task for execution on the specified thread. This function may be +// called on any thread. +/// +/*--cef()--*/ +bool CefPostTask(CefThreadId threadId, CefRefPtr task); + +/// +// Post a task for delayed execution on the specified thread. This function may +// be called on any thread. +/// +/*--cef()--*/ +bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr task, + int64 delay_ms); + + +/// +// Implement this interface for task execution. The methods of this class may +// be called on any thread. +/// +/*--cef(source=client)--*/ +class CefTask : public virtual CefBase { + public: + /// + // Method that will be executed. |threadId| is the thread executing the call. + /// + /*--cef()--*/ + virtual void Execute(CefThreadId threadId) =0; +}; + +#endif // CEF_INCLUDE_CEF_TASK_H_ diff --git a/cefpython/cef1/include/cef_url.h b/cefpython/cef1/include/cef_url.h new file mode 100644 index 00000000..6caa1e22 --- /dev/null +++ b/cefpython/cef1/include/cef_url.h @@ -0,0 +1,60 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_URL_H_ +#define CEF_INCLUDE_CEF_URL_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Parse the specified |url| into its component parts. +// Returns false if the URL is empty or invalid. +/// +/*--cef()--*/ +bool CefParseURL(const CefString& url, + CefURLParts& parts); + +/// +// Creates a URL from the specified |parts|, which must contain a non-empty +// spec or a non-empty host and path (at a minimum), but not both. +// Returns false if |parts| isn't initialized as described. +/// +/*--cef()--*/ +bool CefCreateURL(const CefURLParts& parts, + CefString& url); + +#endif // CEF_INCLUDE_CEF_URL_H_ diff --git a/cefpython/cef1/include/cef_v8.h b/cefpython/cef1/include/cef_v8.h new file mode 100644 index 00000000..03a16b09 --- /dev/null +++ b/cefpython/cef1/include/cef_v8.h @@ -0,0 +1,851 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_V8_H_ +#define CEF_INCLUDE_CEF_V8_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include + +class CefV8Exception; +class CefV8Handler; +class CefV8StackFrame; +class CefV8Value; + + +/// +// Register a new V8 extension with the specified JavaScript extension code and +// handler. Functions implemented by the handler are prototyped using the +// keyword 'native'. The calling of a native function is restricted to the scope +// in which the prototype of the native function is defined. This function may +// be called on any thread. +// +// Example JavaScript extension code: +//
+//   // create the 'example' global object if it doesn't already exist.
+//   if (!example)
+//     example = {};
+//   // create the 'example.test' global object if it doesn't already exist.
+//   if (!example.test)
+//     example.test = {};
+//   (function() {
+//     // Define the function 'example.test.myfunction'.
+//     example.test.myfunction = function() {
+//       // Call CefV8Handler::Execute() with the function name 'MyFunction'
+//       // and no arguments.
+//       native function MyFunction();
+//       return MyFunction();
+//     };
+//     // Define the getter function for parameter 'example.test.myparam'.
+//     example.test.__defineGetter__('myparam', function() {
+//       // Call CefV8Handler::Execute() with the function name 'GetMyParam'
+//       // and no arguments.
+//       native function GetMyParam();
+//       return GetMyParam();
+//     });
+//     // Define the setter function for parameter 'example.test.myparam'.
+//     example.test.__defineSetter__('myparam', function(b) {
+//       // Call CefV8Handler::Execute() with the function name 'SetMyParam'
+//       // and a single argument.
+//       native function SetMyParam();
+//       if(b) SetMyParam(b);
+//     });
+//
+//     // Extension definitions can also contain normal JavaScript variables
+//     // and functions.
+//     var myint = 0;
+//     example.test.increment = function() {
+//       myint += 1;
+//       return myint;
+//     };
+//   })();
+// 
+// Example usage in the page: +//
+//   // Call the function.
+//   example.test.myfunction();
+//   // Set the parameter.
+//   example.test.myparam = value;
+//   // Get the parameter.
+//   value = example.test.myparam;
+//   // Call another function.
+//   example.test.increment();
+// 
+/// +/*--cef(optional_param=handler)--*/ +bool CefRegisterExtension(const CefString& extension_name, + const CefString& javascript_code, + CefRefPtr handler); + + +/// +// Class that encapsulates a V8 context handle. The methods of this class may +// only be called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8Context : public virtual CefBase { + public: + /// + // Returns the current (top) context object in the V8 context stack. + /// + /*--cef()--*/ + static CefRefPtr GetCurrentContext(); + + /// + // Returns the entered (bottom) context object in the V8 context stack. + /// + /*--cef()--*/ + static CefRefPtr GetEnteredContext(); + + /// + // Returns true if V8 is currently inside a context. + /// + /*--cef()--*/ + static bool InContext(); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the browser for this context. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowser() =0; + + /// + // Returns the frame for this context. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame() =0; + + /// + // Returns the global object for this context. The context must be entered + // before calling this method. + /// + /*--cef()--*/ + virtual CefRefPtr GetGlobal() =0; + + /// + // Enter this context. A context must be explicitly entered before creating a + // V8 Object, Array, Function or Date asynchronously. Exit() must be called + // the same number of times as Enter() before releasing this context. V8 + // objects belong to the context in which they are created. Returns true if + // the scope was entered successfully. + /// + /*--cef()--*/ + virtual bool Enter() =0; + + /// + // Exit this context. Call this method only after calling Enter(). Returns + // true if the scope was exited successfully. + /// + /*--cef()--*/ + virtual bool Exit() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Evaluates the specified JavaScript code using this context's global object. + // On success |retval| will be set to the return value, if any, and the + // function will return true. On failure |exception| will be set to the + // exception, if any, and the function will return false. + /// + /*--cef()--*/ + virtual bool Eval(const CefString& code, + CefRefPtr& retval, + CefRefPtr& exception) =0; +}; + + +typedef std::vector > CefV8ValueList; + +/// +// Interface that should be implemented to handle V8 function calls. The methods +// of this class will always be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefV8Handler : public virtual CefBase { + public: + /// + // Handle execution of the function identified by |name|. |object| is the + // receiver ('this' object) of the function. |arguments| is the list of + // arguments passed to the function. If execution succeeds set |retval| to the + // function return value. If execution fails set |exception| to the exception + // that will be thrown. Return true if execution was handled. + /// + /*--cef()--*/ + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) =0; +}; + +/// +// Interface that should be implemented to handle V8 accessor calls. Accessor +// identifiers are registered by calling CefV8Value::SetValue(). The methods +// of this class will always be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefV8Accessor : public virtual CefBase { + public: + /// + // Handle retrieval the accessor value identified by |name|. |object| is the + // receiver ('this' object) of the accessor. If retrieval succeeds set + // |retval| to the return value. If retrieval fails set |exception| to the + // exception that will be thrown. Return true if accessor retrieval was + // handled. + /// + /*--cef()--*/ + virtual bool Get(const CefString& name, + const CefRefPtr object, + CefRefPtr& retval, + CefString& exception) =0; + + /// + // Handle assignment of the accessor value identified by |name|. |object| is + // the receiver ('this' object) of the accessor. |value| is the new value + // being assigned to the accessor. If assignment fails set |exception| to the + // exception that will be thrown. Return true if accessor assignment was + // handled. + /// + /*--cef()--*/ + virtual bool Set(const CefString& name, + const CefRefPtr object, + const CefRefPtr value, + CefString& exception) =0; +}; + +/// +// Class representing a V8 exception. +/// +/*--cef(source=library)--*/ +class CefV8Exception : public virtual CefBase { + public: + /// + // Returns the exception message. + /// + /*--cef()--*/ + virtual CefString GetMessage() =0; + + /// + // Returns the line of source code that the exception occurred within. + /// + /*--cef()--*/ + virtual CefString GetSourceLine() =0; + + /// + // Returns the resource name for the script from where the function causing + // the error originates. + /// + /*--cef()--*/ + virtual CefString GetScriptResourceName() =0; + + /// + // Returns the 1-based number of the line where the error occurred or 0 if the + // line number is unknown. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + /// + // Returns the index within the script of the first character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetStartPosition() =0; + + /// + // Returns the index within the script of the last character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetEndPosition() =0; + + /// + // Returns the index within the line of the first character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetStartColumn() =0; + + /// + // Returns the index within the line of the last character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetEndColumn() =0; +}; + +/// +// Class representing a V8 value. The methods of this class may only be called +// on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8Value : public virtual CefBase { + public: + typedef cef_v8_accesscontrol_t AccessControl; + typedef cef_v8_propertyattribute_t PropertyAttribute; + + /// + // Create a new CefV8Value object of type undefined. + /// + /*--cef()--*/ + static CefRefPtr CreateUndefined(); + + /// + // Create a new CefV8Value object of type null. + /// + /*--cef()--*/ + static CefRefPtr CreateNull(); + + /// + // Create a new CefV8Value object of type bool. + /// + /*--cef()--*/ + static CefRefPtr CreateBool(bool value); + + /// + // Create a new CefV8Value object of type int. + /// + /*--cef()--*/ + static CefRefPtr CreateInt(int32 value); + + /// + // Create a new CefV8Value object of type unsigned int. + /// + /*--cef()--*/ + static CefRefPtr CreateUInt(uint32 value); + + /// + // Create a new CefV8Value object of type double. + /// + /*--cef()--*/ + static CefRefPtr CreateDouble(double value); + + /// + // Create a new CefV8Value object of type Date. This method should only be + // called from within the scope of a CefV8ContextHandler, CefV8Handler or + // CefV8Accessor callback, or in combination with calling Enter() and Exit() + // on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateDate(const CefTime& date); + + /// + // Create a new CefV8Value object of type string. + /// + /*--cef(optional_param=value)--*/ + static CefRefPtr CreateString(const CefString& value); + + /// + // Create a new CefV8Value object of type object with optional accessor. This + // method should only be called from within the scope of a + // CefV8ContextHandler, CefV8Handler or CefV8Accessor callback, or in + // combination with calling Enter() and Exit() on a stored CefV8Context + // reference. + /// + /*--cef(optional_param=accessor)--*/ + static CefRefPtr CreateObject(CefRefPtr accessor); + + /// + // Create a new CefV8Value object of type array with the specified |length|. + // If |length| is negative the returned array will have length 0. This method + // should only be called from within the scope of a CefV8ContextHandler, + // CefV8Handler or CefV8Accessor callback, or in combination with calling + // Enter() and Exit() on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateArray(int length); + + /// + // Create a new CefV8Value object of type function. This method should only be + // called from within the scope of a CefV8ContextHandler, CefV8Handler or + // CefV8Accessor callback, or in combination with calling Enter() and Exit() + // on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateFunction(const CefString& name, + CefRefPtr handler); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // True if the value type is undefined. + /// + /*--cef()--*/ + virtual bool IsUndefined() =0; + + /// + // True if the value type is null. + /// + /*--cef()--*/ + virtual bool IsNull() =0; + + /// + // True if the value type is bool. + /// + /*--cef()--*/ + virtual bool IsBool() =0; + + /// + // True if the value type is int. + /// + /*--cef()--*/ + virtual bool IsInt() =0; + + /// + // True if the value type is unsigned int. + /// + /*--cef()--*/ + virtual bool IsUInt() =0; + + /// + // True if the value type is double. + /// + /*--cef()--*/ + virtual bool IsDouble() =0; + + /// + // True if the value type is Date. + /// + /*--cef()--*/ + virtual bool IsDate() =0; + + /// + // True if the value type is string. + /// + /*--cef()--*/ + virtual bool IsString() =0; + + /// + // True if the value type is object. + /// + /*--cef()--*/ + virtual bool IsObject() =0; + + /// + // True if the value type is array. + /// + /*--cef()--*/ + virtual bool IsArray() =0; + + /// + // True if the value type is function. + /// + /*--cef()--*/ + virtual bool IsFunction() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Return a bool value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual bool GetBoolValue() =0; + + /// + // Return an int value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual int32 GetIntValue() =0; + + /// + // Return an unisgned int value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual uint32 GetUIntValue() =0; + + /// + // Return a double value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual double GetDoubleValue() =0; + + /// + // Return a Date value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual CefTime GetDateValue() =0; + + /// + // Return a string value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual CefString GetStringValue() =0; + + + // OBJECT METHODS - These methods are only available on objects. Arrays and + // functions are also objects. String- and integer-based keys can be used + // interchangably with the framework converting between them as necessary. + + /// + // Returns true if this is a user created object. + /// + /*--cef()--*/ + virtual bool IsUserCreated() =0; + + /// + // Returns true if the last method call resulted in an exception. This + // attribute exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool HasException() =0; + + /// + // Returns the exception resulting from the last method call. This attribute + // exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual CefRefPtr GetException() =0; + + /// + // Clears the last exception and returns true on success. + /// + /*--cef()--*/ + virtual bool ClearException() =0; + + /// + // Returns true if this object will re-throw future exceptions. This attribute + // exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool WillRethrowExceptions() =0; + + /// + // Set whether this object will re-throw future exceptions. By default + // exceptions are not re-thrown. If a exception is re-thrown the current + // context should not be accessed again until after the exception has been + // caught and not re-thrown. Returns true on success. This attribute exists + // only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool SetRethrowExceptions(bool rethrow) =0; + + /// + // Returns true if the object has a value with the specified identifier. + /// + /*--cef(capi_name=has_value_bykey,optional_param=key)--*/ + virtual bool HasValue(const CefString& key) =0; + + /// + // Returns true if the object has a value with the specified identifier. + /// + /*--cef(capi_name=has_value_byindex,index_param=index)--*/ + virtual bool HasValue(int index) =0; + + /// + // Deletes the value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only and don't-delete values this method will return + // true even though deletion failed. + /// + /*--cef(capi_name=delete_value_bykey,optional_param=key)--*/ + virtual bool DeleteValue(const CefString& key) =0; + + /// + // Deletes the value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly, deletion fails + // or an exception is thrown. For read-only and don't-delete values this + // method will return true even though deletion failed. + /// + /*--cef(capi_name=delete_value_byindex,index_param=index)--*/ + virtual bool DeleteValue(int index) =0; + + /// + // Returns the value with the specified identifier on success. Returns NULL + // if this method is called incorrectly or an exception is thrown. + /// + /*--cef(capi_name=get_value_bykey,optional_param=key)--*/ + virtual CefRefPtr GetValue(const CefString& key) =0; + + /// + // Returns the value with the specified identifier on success. Returns NULL + // if this method is called incorrectly or an exception is thrown. + /// + /*--cef(capi_name=get_value_byindex,index_param=index)--*/ + virtual CefRefPtr GetValue(int index) =0; + + /// + // Associates a value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only values this method will return true even though + // assignment failed. + /// + /*--cef(capi_name=set_value_bykey,optional_param=key)--*/ + virtual bool SetValue(const CefString& key, CefRefPtr value, + PropertyAttribute attribute) =0; + + /// + // Associates a value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only values this method will return true even though + // assignment failed. + /// + /*--cef(capi_name=set_value_byindex,index_param=index)--*/ + virtual bool SetValue(int index, CefRefPtr value) =0; + + /// + // Registers an identifier and returns true on success. Access to the + // identifier will be forwarded to the CefV8Accessor instance passed to + // CefV8Value::CreateObject(). Returns false if this method is called + // incorrectly or an exception is thrown. For read-only values this method + // will return true even though assignment failed. + /// + /*--cef(capi_name=set_value_byaccessor,optional_param=key)--*/ + virtual bool SetValue(const CefString& key, AccessControl settings, + PropertyAttribute attribute) =0; + + /// + // Read the keys for the object's values into the specified vector. Integer- + // based keys will also be returned as strings. + /// + /*--cef()--*/ + virtual bool GetKeys(std::vector& keys) =0; + + /// + // Sets the user data for this object and returns true on success. Returns + // false if this method is called incorrectly. This method can only be called + // on user created objects. + /// + /*--cef(optional_param=user_data)--*/ + virtual bool SetUserData(CefRefPtr user_data) =0; + + /// + // Returns the user data, if any, assigned to this object. + /// + /*--cef()--*/ + virtual CefRefPtr GetUserData() =0; + + /// + // Returns the amount of externally allocated memory registered for the + // object. + /// + /*--cef()--*/ + virtual int GetExternallyAllocatedMemory() =0; + + /// + // Adjusts the amount of registered external memory for the object. Used to + // give V8 an indication of the amount of externally allocated memory that is + // kept alive by JavaScript objects. V8 uses this information to decide when + // to perform global garbage collection. Each CefV8Value tracks the amount of + // external memory associated with it and automatically decreases the global + // total by the appropriate amount on its destruction. |change_in_bytes| + // specifies the number of bytes to adjust by. This method returns the number + // of bytes associated with the object after the adjustment. This method can + // only be called on user created objects. + /// + /*--cef()--*/ + virtual int AdjustExternallyAllocatedMemory(int change_in_bytes) =0; + + + // ARRAY METHODS - These methods are only available on arrays. + + /// + // Returns the number of elements in the array. + /// + /*--cef()--*/ + virtual int GetArrayLength() =0; + + + // FUNCTION METHODS - These methods are only available on functions. + + /// + // Returns the function name. + /// + /*--cef()--*/ + virtual CefString GetFunctionName() =0; + + /// + // Returns the function handler or NULL if not a CEF-created function. + /// + /*--cef()--*/ + virtual CefRefPtr GetFunctionHandler() =0; + + /// + // Execute the function using the current V8 context. This method should only + // be called from within the scope of a CefV8Handler or CefV8Accessor + // callback, or in combination with calling Enter() and Exit() on a stored + // CefV8Context reference. |object| is the receiver ('this' object) of the + // function. If |object| is empty the current context's global object will be + // used. |arguments| is the list of arguments that will be passed to the + // function. Returns the function return value on success. Returns NULL if + // this method is called incorrectly or an exception is thrown. + /// + /*--cef(optional_param=object)--*/ + virtual CefRefPtr ExecuteFunction( + CefRefPtr object, + const CefV8ValueList& arguments) =0; + + /// + // Execute the function using the specified V8 context. |object| is the + // receiver ('this' object) of the function. If |object| is empty the + // specified context's global object will be used. |arguments| is the list of + // arguments that will be passed to the function. Returns the function return + // value on success. Returns NULL if this method is called incorrectly or an + // exception is thrown. + /// + /*--cef(optional_param=object)--*/ + virtual CefRefPtr ExecuteFunctionWithContext( + CefRefPtr context, + CefRefPtr object, + const CefV8ValueList& arguments) =0; +}; + +/// +// Class representing a V8 stack trace. The methods of this class may only be +// called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8StackTrace : public virtual CefBase { + public: + /// + // Returns the stack trace for the currently active context. |frame_limit| is + // the maximum number of frames that will be captured. + /// + /*--cef()--*/ + static CefRefPtr GetCurrent(int frame_limit); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the number of stack frames. + /// + /*--cef()--*/ + virtual int GetFrameCount() =0; + + /// + // Returns the stack frame at the specified 0-based index. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame(int index) =0; +}; + +/// +// Class representing a V8 stack frame. The methods of this class may only be +// called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8StackFrame : public virtual CefBase { + public: + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the name of the resource script that contains the function. + /// + /*--cef()--*/ + virtual CefString GetScriptName() =0; + + /// + // Returns the name of the resource script that contains the function or the + // sourceURL value if the script name is undefined and its source ends with + // a "//@ sourceURL=..." string. + /// + /*--cef()--*/ + virtual CefString GetScriptNameOrSourceURL() =0; + + /// + // Returns the name of the function. + /// + /*--cef()--*/ + virtual CefString GetFunctionName() =0; + + /// + // Returns the 1-based line number for the function call or 0 if unknown. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + /// + // Returns the 1-based column offset on the line for the function call or 0 if + // unknown. + /// + /*--cef()--*/ + virtual int GetColumn() =0; + + /// + // Returns true if the function was compiled using eval(). + /// + /*--cef()--*/ + virtual bool IsEval() =0; + + /// + // Returns true if the function was called as a constructor via "new". + /// + /*--cef()--*/ + virtual bool IsConstructor() =0; +}; + +#endif // CEF_INCLUDE_CEF_V8_H_ diff --git a/cefpython/cef1/include/cef_v8context_handler.h b/cefpython/cef1/include/cef_v8context_handler.h new file mode 100644 index 00000000..0483f3f3 --- /dev/null +++ b/cefpython/cef1/include/cef_v8context_handler.h @@ -0,0 +1,85 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_V8CONTEXT_HANDLER_H_ +#define CEF_INCLUDE_CEF_V8CONTEXT_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include "include/cef_v8.h" + +/// +// Implement this interface to handle V8 context events. The methods of this +// class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefV8ContextHandler : public virtual CefBase { + public: + /// + // Called immediately after the V8 context for a frame has been created. To + // retrieve the JavaScript 'window' object use the CefV8Context::GetGlobal() + // method. + /// + /*--cef()--*/ + virtual void OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) {} + + /// + // Called immediately before the V8 context for a frame is released. No + // references to the context should be kept after this method is called. + /// + /*--cef()--*/ + virtual void OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) {} + + /// + // Called for global uncaught exceptions. Execution of this callback is + // disabled by default. To enable set + // CefSettings.uncaught_exception_stack_size > 0. + /// + /*--cef()--*/ + virtual void OnUncaughtException(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) {} +}; + +#endif // CEF_INCLUDE_CEF_V8CONTEXT_HANDLER_H_ diff --git a/cefpython/cef1/include/cef_version.h b/cefpython/cef1/include/cef_version.h new file mode 100644 index 00000000..63db08d2 --- /dev/null +++ b/cefpython/cef1/include/cef_version.h @@ -0,0 +1,68 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file is generated by the make_version_header.py tool. +// + +#ifndef CEF_INCLUDE_CEF_VERSION_H_ +#define CEF_INCLUDE_CEF_VERSION_H_ + +#define CEF_REVISION 1268 +#define COPYRIGHT_YEAR 2013 + +#define CHROME_VERSION_MAJOR 27 +#define CHROME_VERSION_MINOR 0 +#define CHROME_VERSION_BUILD 1453 +#define CHROME_VERSION_PATCH 93 + +#define DO_MAKE_STRING(p) #p +#define MAKE_STRING(p) DO_MAKE_STRING(p) + +#ifndef APSTUDIO_HIDDEN_SYMBOLS + +#ifdef __cplusplus +extern "C" { +#endif + +#include "internal/cef_export.h" + +/// +// Returns the CEF build revision of the libcef library. +/// +CEF_EXPORT int cef_build_revision(); + +#ifdef __cplusplus +} +#endif + +#endif // APSTUDIO_HIDDEN_SYMBOLS + +#endif // CEF_INCLUDE_CEF_VERSION_H_ diff --git a/cefpython/cef1/include/cef_web_plugin.h b/cefpython/cef1/include/cef_web_plugin.h new file mode 100644 index 00000000..e00b2349 --- /dev/null +++ b/cefpython/cef1/include/cef_web_plugin.h @@ -0,0 +1,97 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_WEB_PLUGIN_H_ +#define CEF_INCLUDE_CEF_WEB_PLUGIN_H_ + +#include "include/cef_base.h" + +class CefWebPluginInfo; + +/// +// Returns the number of installed web plugins. This method must be called on +// the UI thread. +/// +/*--cef()--*/ +size_t CefGetWebPluginCount(); + +/// +// Returns information for web plugin at the specified zero-based index. This +// method must be called on the UI thread. +/// +/*--cef()--*/ +CefRefPtr CefGetWebPluginInfo(int index); + +/// +// Returns information for web plugin with the specified name. This method must +// be called on the UI thread. +/// +/*--cef(capi_name=cef_get_web_plugin_info_byname)--*/ +CefRefPtr CefGetWebPluginInfo(const CefString& name); + + +/// +// Information about a specific web plugin. +/// +/*--cef(source=library)--*/ +class CefWebPluginInfo : public virtual CefBase { + public: + /// + // Returns the plugin name (i.e. Flash). + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the plugin file path (DLL/bundle/library). + /// + /*--cef()--*/ + virtual CefString GetPath() =0; + + /// + // Returns the version of the plugin (may be OS-specific). + /// + /*--cef()--*/ + virtual CefString GetVersion() =0; + + /// + // Returns a description of the plugin from the version information. + /// + /*--cef()--*/ + virtual CefString GetDescription() =0; +}; + +#endif // CEF_INCLUDE_CEF_WEB_PLUGIN_H_ diff --git a/cefpython/cef1/include/cef_web_urlrequest.h b/cefpython/cef1/include/cef_web_urlrequest.h new file mode 100644 index 00000000..c5f471f9 --- /dev/null +++ b/cefpython/cef1/include/cef_web_urlrequest.h @@ -0,0 +1,135 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_WEB_URLREQUEST_H_ +#define CEF_INCLUDE_CEF_WEB_URLREQUEST_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_request.h" +#include "include/cef_response.h" + +class CefWebURLRequestClient; + +/// +// Class used to make a Web URL request. Web URL requests are not associated +// with a browser instance so no CefClient callbacks will be executed. The +// methods of this class may be called on any thread. +/// +/*--cef(source=library)--*/ +class CefWebURLRequest : public virtual CefBase { + public: + typedef cef_weburlrequest_state_t RequestState; + + /// + // Create a new CefWebUrlRequest object. + /// + /*--cef()--*/ + static CefRefPtr CreateWebURLRequest( + CefRefPtr request, + CefRefPtr client); + + /// + // Cancels the request. + /// + /*--cef()--*/ + virtual void Cancel() =0; + + /// + // Returns the current ready state of the request. + /// + /*--cef(default_retval=WUR_STATE_UNSENT)--*/ + virtual RequestState GetState() =0; +}; + +/// +// Interface that should be implemented by the CefWebURLRequest client. The +// methods of this class will always be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefWebURLRequestClient : public virtual CefBase { + public: + typedef cef_weburlrequest_state_t RequestState; + typedef cef_handler_errorcode_t ErrorCode; + + /// + // Notifies the client that the request state has changed. State change + // notifications will always be sent before the below notification methods + // are called. + /// + /*--cef()--*/ + virtual void OnStateChange(CefRefPtr requester, + RequestState state) =0; + + /// + // Notifies the client that the request has been redirected and provides a + // chance to change the request parameters. + /// + /*--cef()--*/ + virtual void OnRedirect(CefRefPtr requester, + CefRefPtr request, + CefRefPtr response) =0; + + /// + // Notifies the client of the response data. + /// + /*--cef()--*/ + virtual void OnHeadersReceived(CefRefPtr requester, + CefRefPtr response) =0; + + /// + // Notifies the client of the upload progress. + /// + /*--cef()--*/ + virtual void OnProgress(CefRefPtr requester, + uint64 bytesSent, uint64 totalBytesToBeSent) =0; + + /// + // Notifies the client that content has been received. + /// + /*--cef()--*/ + virtual void OnData(CefRefPtr requester, + const void* data, int dataLength) =0; + + /// + // Notifies the client that the request ended with an error. + /// + /*--cef()--*/ + virtual void OnError(CefRefPtr requester, + ErrorCode errorCode) =0; +}; + +#endif // CEF_INCLUDE_CEF_WEB_URLREQUEST_H_ diff --git a/cefpython/cef1/include/cef_xml_reader.h b/cefpython/cef1/include/cef_xml_reader.h new file mode 100644 index 00000000..e457e0d8 --- /dev/null +++ b/cefpython/cef1/include/cef_xml_reader.h @@ -0,0 +1,268 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_XML_READER_H_ +#define CEF_INCLUDE_CEF_XML_READER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Class that supports the reading of XML data via the libxml streaming API. +// The methods of this class should only be called on the thread that creates +// the object. +/// +/*--cef(source=library)--*/ +class CefXmlReader : public virtual CefBase { + public: + typedef cef_xml_encoding_type_t EncodingType; + typedef cef_xml_node_type_t NodeType; + + /// + // Create a new CefXmlReader object. The returned object's methods can only + // be called from the thread that created the object. + /// + /*--cef()--*/ + static CefRefPtr Create(CefRefPtr stream, + EncodingType encodingType, + const CefString& URI); + + /// + // Moves the cursor to the next node in the document. This method must be + // called at least once to set the current cursor position. Returns true if + // the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextNode() =0; + + /// + // Close the document. This should be called directly to ensure that cleanup + // occurs on the correct thread. + /// + /*--cef()--*/ + virtual bool Close() =0; + + /// + // Returns true if an error has been reported by the XML parser. + /// + /*--cef()--*/ + virtual bool HasError() =0; + + /// + // Returns the error string. + /// + /*--cef()--*/ + virtual CefString GetError() =0; + + + // The below methods retrieve data for the node at the current cursor + // position. + + /// + // Returns the node type. + /// + /*--cef(default_retval=XML_NODE_UNSUPPORTED)--*/ + virtual NodeType GetType() =0; + + /// + // Returns the node depth. Depth starts at 0 for the root node. + /// + /*--cef()--*/ + virtual int GetDepth() =0; + + /// + // Returns the local name. See + // http://www.w3.org/TR/REC-xml-names/#NT-LocalPart for additional details. + /// + /*--cef()--*/ + virtual CefString GetLocalName() =0; + + /// + // Returns the namespace prefix. See http://www.w3.org/TR/REC-xml-names/ for + // additional details. + /// + /*--cef()--*/ + virtual CefString GetPrefix() =0; + + /// + // Returns the qualified name, equal to (Prefix:)LocalName. See + // http://www.w3.org/TR/REC-xml-names/#ns-qualnames for additional details. + /// + /*--cef()--*/ + virtual CefString GetQualifiedName() =0; + + /// + // Returns the URI defining the namespace associated with the node. See + // http://www.w3.org/TR/REC-xml-names/ for additional details. + /// + /*--cef()--*/ + virtual CefString GetNamespaceURI() =0; + + /// + // Returns the base URI of the node. See http://www.w3.org/TR/xmlbase/ for + // additional details. + /// + /*--cef()--*/ + virtual CefString GetBaseURI() =0; + + /// + // Returns the xml:lang scope within which the node resides. See + // http://www.w3.org/TR/REC-xml/#sec-lang-tag for additional details. + /// + /*--cef()--*/ + virtual CefString GetXmlLang() =0; + + /// + // Returns true if the node represents an empty element. is considered + // empty but is not. + /// + /*--cef()--*/ + virtual bool IsEmptyElement() =0; + + /// + // Returns true if the node has a text value. + /// + /*--cef()--*/ + virtual bool HasValue() =0; + + /// + // Returns the text value. + /// + /*--cef()--*/ + virtual CefString GetValue() =0; + + /// + // Returns true if the node has attributes. + /// + /*--cef()--*/ + virtual bool HasAttributes() =0; + + /// + // Returns the number of attributes. + /// + /*--cef()--*/ + virtual size_t GetAttributeCount() =0; + + /// + // Returns the value of the attribute at the specified 0-based index. + /// + /*--cef(capi_name=get_attribute_byindex,index_param=index)--*/ + virtual CefString GetAttribute(int index) =0; + + /// + // Returns the value of the attribute with the specified qualified name. + /// + /*--cef(capi_name=get_attribute_byqname)--*/ + virtual CefString GetAttribute(const CefString& qualifiedName) =0; + + /// + // Returns the value of the attribute with the specified local name and + // namespace URI. + /// + /*--cef(capi_name=get_attribute_bylname)--*/ + virtual CefString GetAttribute(const CefString& localName, + const CefString& namespaceURI) =0; + + /// + // Returns an XML representation of the current node's children. + /// + /*--cef()--*/ + virtual CefString GetInnerXml() =0; + + /// + // Returns an XML representation of the current node including its children. + /// + /*--cef()--*/ + virtual CefString GetOuterXml() =0; + + /// + // Returns the line number for the current node. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + + // Attribute nodes are not traversed by default. The below methods can be + // used to move the cursor to an attribute node. MoveToCarryingElement() can + // be called afterwards to return the cursor to the carrying element. The + // depth of an attribute node will be 1 + the depth of the carrying element. + + /// + // Moves the cursor to the attribute at the specified 0-based index. Returns + // true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_byindex,index_param=index)--*/ + virtual bool MoveToAttribute(int index) =0; + + /// + // Moves the cursor to the attribute with the specified qualified name. + // Returns true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_byqname)--*/ + virtual bool MoveToAttribute(const CefString& qualifiedName) =0; + + /// + // Moves the cursor to the attribute with the specified local name and + // namespace URI. Returns true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_bylname)--*/ + virtual bool MoveToAttribute(const CefString& localName, + const CefString& namespaceURI) =0; + + /// + // Moves the cursor to the first attribute in the current element. Returns + // true if the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFirstAttribute() =0; + + /// + // Moves the cursor to the next attribute in the current element. Returns + // true if the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextAttribute() =0; + + /// + // Moves the cursor back to the carrying element. Returns true if the cursor + // position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToCarryingElement() =0; +}; + +#endif // CEF_INCLUDE_CEF_XML_READER_H_ diff --git a/cefpython/cef1/include/cef_zip_reader.h b/cefpython/cef1/include/cef_zip_reader.h new file mode 100644 index 00000000..9498f06e --- /dev/null +++ b/cefpython/cef1/include/cef_zip_reader.h @@ -0,0 +1,141 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_ZIP_READER_H_ +#define CEF_INCLUDE_CEF_ZIP_READER_H_ + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Class that supports the reading of zip archives via the zlib unzip API. +// The methods of this class should only be called on the thread that creates +// the object. +/// +/*--cef(source=library)--*/ +class CefZipReader : public virtual CefBase { + public: + /// + // Create a new CefZipReader object. The returned object's methods can only + // be called from the thread that created the object. + /// + /*--cef()--*/ + static CefRefPtr Create(CefRefPtr stream); + + /// + // Moves the cursor to the first file in the archive. Returns true if the + // cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFirstFile() =0; + + /// + // Moves the cursor to the next file in the archive. Returns true if the + // cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextFile() =0; + + /// + // Moves the cursor to the specified file in the archive. If |caseSensitive| + // is true then the search will be case sensitive. Returns true if the cursor + // position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFile(const CefString& fileName, bool caseSensitive) =0; + + /// + // Closes the archive. This should be called directly to ensure that cleanup + // occurs on the correct thread. + /// + /*--cef()--*/ + virtual bool Close() =0; + + + // The below methods act on the file at the current cursor position. + + /// + // Returns the name of the file. + /// + /*--cef()--*/ + virtual CefString GetFileName() =0; + + /// + // Returns the uncompressed size of the file. + /// + /*--cef()--*/ + virtual int64 GetFileSize() =0; + + /// + // Returns the last modified timestamp for the file. + /// + /*--cef()--*/ + virtual time_t GetFileLastModified() =0; + + /// + // Opens the file for reading of uncompressed data. A read password may + // optionally be specified. + /// + /*--cef(optional_param=password)--*/ + virtual bool OpenFile(const CefString& password) =0; + + /// + // Closes the file. + /// + /*--cef()--*/ + virtual bool CloseFile() =0; + + /// + // Read uncompressed file contents into the specified buffer. Returns < 0 if + // an error occurred, 0 if at the end of file, or the number of bytes read. + /// + /*--cef()--*/ + virtual int ReadFile(void* buffer, size_t bufferSize) =0; + + /// + // Returns the current offset in the uncompressed file contents. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Returns true if at end of the file contents. + /// + /*--cef()--*/ + virtual bool Eof() =0; +}; + +#endif // CEF_INCLUDE_CEF_ZIP_READER_H_ diff --git a/cefpython/cef1/include/cef_zoom_handler.h b/cefpython/cef1/include/cef_zoom_handler.h new file mode 100644 index 00000000..7062b64b --- /dev/null +++ b/cefpython/cef1/include/cef_zoom_handler.h @@ -0,0 +1,72 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_ZOOM_HANDLER_H_ +#define CEF_INCLUDE_CEF_ZOOM_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to customize zoom handling. The methods of this +// class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefZoomHandler : public virtual CefBase { + public: + /// + // Called when the browser wants to retrieve the zoom level for the given + // |url|. Return true if |zoomLevel| has been set to the custom zoom level. + // Return false for the browser's default zoom handling behavior. + /// + /*--cef()--*/ + virtual bool OnGetZoomLevel(CefRefPtr browser, + const CefString& url, + double& zoomLevel) { return false; } + + /// + // Called when the browser's zoom level has been set to |zoomLevel| for the + // given |url|. Return true to indicate that the new setting has been handled. + // Return false to use the browser's default zoom handling behavior. + /// + /*--cef()--*/ + virtual bool OnSetZoomLevel(CefRefPtr browser, + const CefString& url, + double zoomLevel) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_ZOOM_HANDLER_H_ diff --git a/cefpython/cef1/include/internal/cef_build.h b/cefpython/cef1/include/internal/cef_build.h new file mode 100644 index 00000000..4b8c5454 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_build.h @@ -0,0 +1,129 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ +#define CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ +#pragma once + +#if defined(BUILDING_CEF_SHARED) + +#include "base/compiler_specific.h" + +#else // !BUILDING_CEF_SHARED + +#if defined(_WIN32) +#ifndef OS_WIN +#define OS_WIN 1 +#endif +#elif defined(__APPLE__) +#ifndef OS_MACOSX +#define OS_MACOSX 1 +#endif +#elif defined(__linux__) +#ifndef OS_LINUX +#define OS_LINUX 1 +#endif +#else +#error Please add support for your platform in cef_build.h +#endif + +// For access to standard POSIXish features, use OS_POSIX instead of a +// more specific macro. +#if defined(OS_MACOSX) || defined(OS_LINUX) +#ifndef OS_POSIX +#define OS_POSIX 1 +#endif +#endif + +// Compiler detection. +#if defined(__GNUC__) +#ifndef COMPILER_GCC +#define COMPILER_GCC 1 +#endif +#elif defined(_MSC_VER) +#ifndef COMPILER_MSVC +#define COMPILER_MSVC 1 +#endif +#else +#error Please add support for your compiler in cef_build.h +#endif + +// Annotate a virtual method indicating it must be overriding a virtual +// method in the parent class. +// Use like: +// virtual void foo() OVERRIDE; +#ifndef OVERRIDE +#if defined(COMPILER_MSVC) +#define OVERRIDE override +#elif defined(__clang__) +#define OVERRIDE override +#else +#define OVERRIDE +#endif +#endif + +#ifndef ALLOW_THIS_IN_INITIALIZER_LIST +#if defined(COMPILER_MSVC) + +// MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. +// The warning remains disabled until popped by MSVC_POP_WARNING. +#define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ + __pragma(warning(disable:n)) + +// MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level +// remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all +// warnings. +#define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) + +// Pop effects of innermost MSVC_PUSH_* macro. +#define MSVC_POP_WARNING() __pragma(warning(pop)) + +// Allows |this| to be passed as an argument in constructor initializer lists. +// This uses push/pop instead of the seemingly simpler suppress feature to avoid +// having the warning be disabled for more than just |code|. +// +// Example usage: +// Foo::Foo() : x(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(y(this)), z(3) {} +// +// Compiler warning C4355: 'this': used in base member initializer list: +// http://msdn.microsoft.com/en-us/library/3c594ae3(VS.80).aspx +#define ALLOW_THIS_IN_INITIALIZER_LIST(code) MSVC_PUSH_DISABLE_WARNING(4355) \ + code \ + MSVC_POP_WARNING() +#else // !COMPILER_MSVC + +#define ALLOW_THIS_IN_INITIALIZER_LIST(code) code + +#endif // !COMPILER_MSVC +#endif + +#endif // !BUILDING_CEF_SHARED + +#endif // CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ diff --git a/cefpython/cef1/include/internal/cef_export.h b/cefpython/cef1/include/internal/cef_export.h new file mode 100644 index 00000000..d333a5db --- /dev/null +++ b/cefpython/cef1/include/internal/cef_export.h @@ -0,0 +1,55 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights +// reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ +#define CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(COMPILER_MSVC) + +#ifdef BUILDING_CEF_SHARED +#define CEF_EXPORT __declspec(dllexport) +#elif USING_CEF_SHARED +#define CEF_EXPORT __declspec(dllimport) +#else +#define CEF_EXPORT +#endif +#define CEF_CALLBACK __stdcall + +#elif defined(COMPILER_GCC) + +#define CEF_EXPORT __attribute__ ((visibility("default"))) +#define CEF_CALLBACK + +#endif // COMPILER_GCC + +#endif // CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ diff --git a/cefpython/cef1/include/internal/cef_linux.h b/cefpython/cef1/include/internal/cef_linux.h new file mode 100644 index 00000000..0c9003b0 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_linux.h @@ -0,0 +1,149 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ +#define CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ +#pragma once + +#if defined(OS_LINUX) +#include +#include "include/internal/cef_types_linux.h" +#include "include/internal/cef_types_wrappers.h" + +/// +// Atomic increment and decrement. +/// +inline long CefAtomicIncrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_add_and_fetch(pDest, 1); +} +inline long CefAtomicDecrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_sub_and_fetch(pDest, 1); +} + +/// +// Critical section wrapper. +/// +class CefCriticalSection { + public: + CefCriticalSection() { + pthread_mutexattr_init(&attr_); + pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock_, &attr_); + } + virtual ~CefCriticalSection() { + pthread_mutex_destroy(&lock_); + pthread_mutexattr_destroy(&attr_); + } + void Lock() { + pthread_mutex_lock(&lock_); + } + void Unlock() { + pthread_mutex_unlock(&lock_); + } + + pthread_mutex_t lock_; + pthread_mutexattr_t attr_; +}; + +/// +// Handle types. +/// +#define CefWindowHandle cef_window_handle_t +#define CefCursorHandle cef_cursor_handle_t + + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_Widget = src->m_Widget; + target->m_ParentWidget = src->m_ParentWidget; + } +}; + +/// +// Class representing window information. +/// +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(CefWindowHandle ParentWidget) { + m_ParentWidget = ParentWidget; + } +}; + + +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_Scale = src->m_Scale; + } +}; + +/// +// Class representing print context information. +/// +typedef CefStructBase CefPrintInfo; + + +struct CefKeyInfoTraits { + typedef cef_key_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->key = src->key; + } +}; + +/// +// Class representing key information. +/// +typedef CefStructBase CefKeyInfo; + +#endif // OS_LINUX + +#endif // CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ diff --git a/cefpython/cef1/include/internal/cef_mac.h b/cefpython/cef1/include/internal/cef_mac.h new file mode 100644 index 00000000..d979e80f --- /dev/null +++ b/cefpython/cef1/include/internal/cef_mac.h @@ -0,0 +1,178 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_MAC_H_ +#define CEF_INCLUDE_INTERNAL_CEF_MAC_H_ +#pragma once + +#if defined(OS_MACOSX) +#include +#include "include/internal/cef_types_mac.h" +#include "include/internal/cef_types_wrappers.h" + +/// +// Atomic increment and decrement. +/// +inline long CefAtomicIncrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_add_and_fetch(pDest, 1); +} +inline long CefAtomicDecrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_sub_and_fetch(pDest, 1); +} + +/// +// Handle types. +/// +#define CefWindowHandle cef_window_handle_t +#define CefCursorHandle cef_cursor_handle_t + +/// +// Critical section wrapper. +/// +class CefCriticalSection { + public: + CefCriticalSection() { + pthread_mutexattr_init(&attr_); + pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock_, &attr_); + } + virtual ~CefCriticalSection() { + pthread_mutex_destroy(&lock_); + pthread_mutexattr_destroy(&attr_); + } + void Lock() { + pthread_mutex_lock(&lock_); + } + void Unlock() { + pthread_mutex_unlock(&lock_); + } + + pthread_mutex_t lock_; + pthread_mutexattr_t attr_; +}; + + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->m_windowName); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_View = src->m_View; + target->m_ParentView = src->m_ParentView; + cef_string_set(src->m_windowName.str, src->m_windowName.length, + &target->m_windowName, copy); + target->m_x = src->m_x; + target->m_y = src->m_y; + target->m_nWidth = src->m_nWidth; + target->m_nHeight = src->m_nHeight; + target->m_bHidden = src->m_bHidden; + target->m_bWindowRenderingDisabled = src->m_bWindowRenderingDisabled; + target->m_bTransparentPainting = src->m_bTransparentPainting; + } +}; + +/// +// Class representing window information. +/// +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(CefWindowHandle ParentView, int x, int y, int width, + int height) { + m_ParentView = ParentView; + m_x = x; + m_y = y; + m_nWidth = width; + m_nHeight = height; + m_bHidden = false; + } + + void SetAsOffScreen(NSView* parent) { + m_bWindowRenderingDisabled = true; + m_ParentView = parent; + } + + void SetTransparentPainting(int transparentPainting) { + m_bTransparentPainting = transparentPainting; + } +}; + + +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_Scale = src->m_Scale; + } +}; + +/// +// Class representing print context information. +/// +typedef CefStructBase CefPrintInfo; + +struct CefKeyInfoTraits { + typedef cef_key_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->keyCode = src->keyCode; + target->character = src->character; + target->characterNoModifiers = src->characterNoModifiers; + } +}; + +/// +// Class representing key information. +/// +typedef CefStructBase CefKeyInfo; + + +#endif // OS_MACOSX + +#endif // CEF_INCLUDE_INTERNAL_CEF_MAC_H_ diff --git a/cefpython/cef1/include/internal/cef_nplugin_types.h b/cefpython/cef1/include/internal/cef_nplugin_types.h new file mode 100644 index 00000000..0113f72f --- /dev/null +++ b/cefpython/cef1/include/internal/cef_nplugin_types.h @@ -0,0 +1,90 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_NPLUGIN_TYPES_H_ +#define CEF_INCLUDE_INTERNAL_CEF_NPLUGIN_TYPES_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" +#include "third_party/npapi/bindings/npapi.h" +#include "third_party/npapi/bindings/nphostapi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Netscape plugins are normally built at separate DLLs that are loaded by the +// browser when needed. This interface supports the creation of plugins that +// are an embedded component of the application. Embedded plugins built using +// this interface use the same Netscape Plugin API as DLL-based plugins. +// See https://developer.mozilla.org/En/Gecko_Plugin_API_Reference for complete +// documentation on how to use the Netscape Plugin API. + +// This structure provides attribute information and entry point functions for +// a plugin. +typedef struct _cef_plugin_info_t { + // The unique name that identifies the plugin. + cef_string_t unique_name; + + // The friendly display name of the plugin. + cef_string_t display_name; + + // The version string of the plugin. + cef_string_t version; + + // A description of the plugin. + cef_string_t description; + + // A pipe (|) delimited list of mime type values that the plugin supports. + cef_string_t mime_types; + + // A pipe (|) delimited list of extension values. Each value is associated + // with the mime type value at the same position. Multiple file extensions + // for the same mime type may be delimited with commas (,). + cef_string_t file_extensions; + + // A pipe (|) delimited list of description values. Each value is associated + // with the mime type value at the same position. + cef_string_t type_descriptions; + + // Entry point function pointers. +#if !defined(OS_POSIX) || defined(OS_MACOSX) + NP_GetEntryPointsFunc np_getentrypoints; +#endif + NP_InitializeFunc np_initialize; + NP_ShutdownFunc np_shutdown; +} cef_plugin_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_NPLUGIN_TYPES_H_ diff --git a/cefpython/cef1/include/internal/cef_ptr.h b/cefpython/cef1/include/internal/cef_ptr.h new file mode 100644 index 00000000..fcbe69e5 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_ptr.h @@ -0,0 +1,199 @@ +// Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2008 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_PTR_H_ +#define CEF_INCLUDE_INTERNAL_CEF_PTR_H_ +#pragma once + +#include + +/// +// Smart pointer implementation borrowed from base/ref_counted.h +//

+// A smart pointer class for reference counted objects. Use this class instead +// of calling AddRef and Release manually on a reference counted object to +// avoid common memory leaks caused by forgetting to Release an object +// reference. Sample usage: +//

+//   class MyFoo : public CefBase {
+//    ...
+//   };
+//
+//   void some_function() {
+//     // The MyFoo object that |foo| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//     foo->Method(param);
+//     // |foo| is released when this function returns
+//   }
+//
+//   void some_other_function() {
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//     ...
+//     foo = NULL;  // explicitly releases |foo|
+//     ...
+//     if (foo)
+//       foo->Method(param);
+//   }
+// 
+// The above examples show how CefRefPtr<T> acts like a pointer to T. +// Given two CefRefPtr<T> classes, it is also possible to exchange +// references between the two objects, like so: +//
+//   {
+//     CefRefPtr<MyFoo> a = new MyFoo();
+//     CefRefPtr<MyFoo> b;
+//
+//     b.swap(a);
+//     // now, |b| references the MyFoo object, and |a| references NULL.
+//   }
+// 
+// To make both |a| and |b| in the above example reference the same MyFoo +// object, simply use the assignment operator: +//
+//   {
+//     CefRefPtr<MyFoo> a = new MyFoo();
+//     CefRefPtr<MyFoo> b;
+//
+//     b = a;
+//     // now, |a| and |b| each own a reference to the same MyFoo object.
+//     // the reference count of the underlying MyFoo object will be 2.
+//   }
+// 
+// Reference counted objects can also be passed as function parameters and +// used as function return values: +//
+//   void some_func_with_param(CefRefPtr<MyFoo> param) {
+//     // A reference is added to the MyFoo object that |param| represents
+//     // during the scope of some_func_with_param() and released when
+//     // some_func_with_param() goes out of scope.
+//   }
+//
+//   CefRefPtr<MyFoo> some_func_with_retval() {
+//     // The MyFoo object that |foox| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foox = new MyFoo();
+//
+//     // Creating the return value adds an additional reference.
+//     return foox;
+//
+//     // When some_func_with_retval() goes out of scope the original |foox|
+//     // reference is released.
+//   }
+//
+//   void and_another_function() {
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//
+//     // pass |foo| as a parameter.
+//     some_function(foo);
+//
+//     CefRefPtr<MyFoo> foo2 = some_func_with_retval();
+//     // Now, since we kept a reference to the some_func_with_retval() return
+//     // value, |foo2| is the only class pointing to the MyFoo object created
+//     in some_func_with_retval(), and it has a reference count of 1.
+//
+//     some_func_with_retval();
+//     // Now, since we didn't keep a reference to the some_func_with_retval()
+//     // return value, the MyFoo object created in some_func_with_retval()
+//     // will automatically be released.
+//   }
+// 
+// And in standard containers: +//
+//   {
+//      // Create a vector that holds MyFoo objects.
+//      std::vector<CefRefPtr<MyFoo> > MyFooVec;
+//
+//     // The MyFoo object that |foo| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//
+//     // When the MyFoo object is added to |MyFooVec| the reference count
+//     // is increased to 2.
+//     MyFooVec.push_back(foo);
+//   }
+// 
+//

+/// +template +class CefRefPtr { + public: + CefRefPtr() : ptr_(NULL) { + } + + CefRefPtr(T* p) : ptr_(p) { // NOLINT(runtime/explicit) + if (ptr_) + ptr_->AddRef(); + } + + CefRefPtr(const CefRefPtr& r) : ptr_(r.ptr_) { + if (ptr_) + ptr_->AddRef(); + } + + ~CefRefPtr() { + if (ptr_) + ptr_->Release(); + } + + T* get() const { return ptr_; } + operator T*() const { return ptr_; } + T* operator->() const { return ptr_; } + + CefRefPtr& operator=(T* p) { + // AddRef first so that self assignment should work + if (p) + p->AddRef(); + if (ptr_ ) + ptr_ ->Release(); + ptr_ = p; + return *this; + } + + CefRefPtr& operator=(const CefRefPtr& r) { + return *this = r.ptr_; + } + + void swap(T** pp) { + T* p = ptr_; + ptr_ = *pp; + *pp = p; + } + + void swap(CefRefPtr& r) { + swap(&r.ptr_); // NOLINT(build/include_what_you_use) + } + + private: + T* ptr_; +}; + +#endif // CEF_INCLUDE_INTERNAL_CEF_PTR_H_ diff --git a/cefpython/cef1/include/internal/cef_string.h b/cefpython/cef1/include/internal/cef_string.h new file mode 100644 index 00000000..a7876fe5 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string.h @@ -0,0 +1,113 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_H_ +#pragma once + +// The CEF interface is built with one string type as the default. Comment out +// all but one of the CEF_STRING_TYPE_* defines below to specify the default. +// If you change the default you MUST recompile all of CEF. + +// Build with the UTF8 string type as default. +// #define CEF_STRING_TYPE_UTF8 1 + +// Build with the UTF16 string type as default. +#define CEF_STRING_TYPE_UTF16 1 + +// Build with the wide string type as default. +// #define CEF_STRING_TYPE_WIDE 1 + + +#include "include/internal/cef_string_types.h" + +#ifdef __cplusplus +#include "include/internal/cef_string_wrappers.h" +#if defined(CEF_STRING_TYPE_UTF16) +typedef CefStringUTF16 CefString; +#elif defined(CEF_STRING_TYPE_UTF8) +typedef CefStringUTF8 CefString; +#elif defined(CEF_STRING_TYPE_WIDE) +typedef CefStringWide CefString; +#endif +#endif // __cplusplus + +#if defined(CEF_STRING_TYPE_UTF8) +typedef char cef_char_t; +typedef cef_string_utf8_t cef_string_t; +typedef cef_string_userfree_utf8_t cef_string_userfree_t; +#define cef_string_set cef_string_utf8_set +#define cef_string_copy cef_string_utf8_copy +#define cef_string_clear cef_string_utf8_clear +#define cef_string_userfree_alloc cef_string_userfree_utf8_alloc +#define cef_string_userfree_free cef_string_userfree_utf8_free +#define cef_string_from_ascii cef_string_utf8_copy +#define cef_string_to_utf8 cef_string_utf8_copy +#define cef_string_from_utf8 cef_string_utf8_copy +#define cef_string_to_utf16 cef_string_utf8_to_utf16 +#define cef_string_from_utf16 cef_string_utf16_to_utf8 +#define cef_string_to_wide cef_string_utf8_to_wide +#define cef_string_from_wide cef_string_wide_to_utf8 +#elif defined(CEF_STRING_TYPE_UTF16) +typedef char16 cef_char_t; +typedef cef_string_userfree_utf16_t cef_string_userfree_t; +typedef cef_string_utf16_t cef_string_t; +#define cef_string_set cef_string_utf16_set +#define cef_string_copy cef_string_utf16_copy +#define cef_string_clear cef_string_utf16_clear +#define cef_string_userfree_alloc cef_string_userfree_utf16_alloc +#define cef_string_userfree_free cef_string_userfree_utf16_free +#define cef_string_from_ascii cef_string_ascii_to_utf16 +#define cef_string_to_utf8 cef_string_utf16_to_utf8 +#define cef_string_from_utf8 cef_string_utf8_to_utf16 +#define cef_string_to_utf16 cef_string_utf16_copy +#define cef_string_from_utf16 cef_string_utf16_copy +#define cef_string_to_wide cef_string_utf16_to_wide +#define cef_string_from_wide cef_string_wide_to_utf16 +#elif defined(CEF_STRING_TYPE_WIDE) +typedef wchar_t cef_char_t; +typedef cef_string_wide_t cef_string_t; +typedef cef_string_userfree_wide_t cef_string_userfree_t; +#define cef_string_set cef_string_wide_set +#define cef_string_copy cef_string_wide_copy +#define cef_string_clear cef_string_wide_clear +#define cef_string_userfree_alloc cef_string_userfree_wide_alloc +#define cef_string_userfree_free cef_string_userfree_wide_free +#define cef_string_from_ascii cef_string_ascii_to_wide +#define cef_string_to_utf8 cef_string_wide_to_utf8 +#define cef_string_from_utf8 cef_string_utf8_to_wide +#define cef_string_to_utf16 cef_string_wide_to_utf16 +#define cef_string_from_utf16 cef_string_utf16_to_wide +#define cef_string_to_wide cef_string_wide_copy +#define cef_string_from_wide cef_string_wide_copy +#else +#error Please choose a string type. +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_H_ diff --git a/cefpython/cef1/include/internal/cef_string_list.h b/cefpython/cef1/include/internal/cef_string_list.h new file mode 100644 index 00000000..52a0abf2 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string_list.h @@ -0,0 +1,88 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string maps are a set of key/value string pairs. +/// +typedef void* cef_string_list_t; + +/// +// Allocate a new string map. +/// +CEF_EXPORT cef_string_list_t cef_string_list_alloc(); + +/// +// Return the number of elements in the string list. +/// +CEF_EXPORT int cef_string_list_size(cef_string_list_t list); + +/// +// Retrieve the value at the specified zero-based string list index. Returns +// true (1) if the value was successfully retrieved. +/// +CEF_EXPORT int cef_string_list_value(cef_string_list_t list, + int index, cef_string_t* value); + +/// +// Append a new value at the end of the string list. +/// +CEF_EXPORT void cef_string_list_append(cef_string_list_t list, + const cef_string_t* value); + +/// +// Clear the string list. +/// +CEF_EXPORT void cef_string_list_clear(cef_string_list_t list); + +/// +// Free the string list. +/// +CEF_EXPORT void cef_string_list_free(cef_string_list_t list); + +/// +// Creates a copy of an existing string list. +/// +CEF_EXPORT cef_string_list_t cef_string_list_copy(cef_string_list_t list); + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ diff --git a/cefpython/cef1/include/internal/cef_string_map.h b/cefpython/cef1/include/internal/cef_string_map.h new file mode 100644 index 00000000..93eea2a5 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string_map.h @@ -0,0 +1,97 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string maps are a set of key/value string pairs. +/// +typedef void* cef_string_map_t; + +/// +// Allocate a new string map. +/// +CEF_EXPORT cef_string_map_t cef_string_map_alloc(); + +/// +// Return the number of elements in the string map. +/// +CEF_EXPORT int cef_string_map_size(cef_string_map_t map); + +/// +// Return the value assigned to the specified key. +/// +CEF_EXPORT int cef_string_map_find(cef_string_map_t map, + const cef_string_t* key, + cef_string_t* value); + +/// +// Return the key at the specified zero-based string map index. +/// +CEF_EXPORT int cef_string_map_key(cef_string_map_t map, int index, + cef_string_t* key); + +/// +// Return the value at the specified zero-based string map index. +/// +CEF_EXPORT int cef_string_map_value(cef_string_map_t map, int index, + cef_string_t* value); + +/// +// Append a new key/value pair at the end of the string map. +/// +CEF_EXPORT int cef_string_map_append(cef_string_map_t map, + const cef_string_t* key, + const cef_string_t* value); + +/// +// Clear the string map. +/// +CEF_EXPORT void cef_string_map_clear(cef_string_map_t map); + +/// +// Free the string map. +/// +CEF_EXPORT void cef_string_map_free(cef_string_map_t map); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ diff --git a/cefpython/cef1/include/internal/cef_string_multimap.h b/cefpython/cef1/include/internal/cef_string_multimap.h new file mode 100644 index 00000000..cd390424 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string_multimap.h @@ -0,0 +1,105 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string multimaps are a set of key/value string pairs. +// More than one value can be assigned to a single key. +/// +typedef void* cef_string_multimap_t; + +/// +// Allocate a new string multimap. +/// +CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc(); + +/// +// Return the number of elements in the string multimap. +/// +CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map); + +/// +// Return the number of values with the specified key. +/// +CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map, + const cef_string_t* key); + +/// +// Return the value_index-th value with the specified key. +/// +CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map, + const cef_string_t* key, + int value_index, + cef_string_t* value); + +/// +// Return the key at the specified zero-based string multimap index. +/// +CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index, + cef_string_t* key); + +/// +// Return the value at the specified zero-based string multimap index. +/// +CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index, + cef_string_t* value); + +/// +// Append a new key/value pair at the end of the string multimap. +/// +CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map, + const cef_string_t* key, + const cef_string_t* value); + +/// +// Clear the string multimap. +/// +CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map); + +/// +// Free the string multimap. +/// +CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ diff --git a/cefpython/cef1/include/internal/cef_string_types.h b/cefpython/cef1/include/internal/cef_string_types.h new file mode 100644 index 00000000..7ab6671c --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string_types.h @@ -0,0 +1,204 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ +#pragma once + +// CEF provides functions for converting between UTF-8, -16 and -32 strings. +// CEF string types are safe for reading from multiple threads but not for +// modification. It is the user's responsibility to provide synchronization if +// modifying CEF strings from multiple threads. + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/internal/cef_build.h" +#include "include/internal/cef_export.h" +#include + +// CEF character type definitions. wchar_t is 2 bytes on Windows and 4 bytes on +// most other platforms. + +#if defined(OS_WIN) +typedef wchar_t char16; +#else // !OS_WIN +typedef unsigned short char16; // NOLINT (runtime/int) +#ifndef WCHAR_T_IS_UTF32 +#define WCHAR_T_IS_UTF32 +#endif // WCHAR_T_IS_UTF32 +#endif // !OS_WIN + + +// CEF string type definitions. Whomever allocates |str| is responsible for +// providing an appropriate |dtor| implementation that will free the string in +// the same memory space. When reusing an existing string structure make sure +// to call |dtor| for the old value before assigning new |str| and |dtor| +// values. Static strings will have a NULL |dtor| value. Using the below +// functions if you want this managed for you. + +typedef struct _cef_string_wide_t { + wchar_t* str; + size_t length; + void (*dtor)(wchar_t* str); +} cef_string_wide_t; + +typedef struct _cef_string_utf8_t { + char* str; + size_t length; + void (*dtor)(char* str); +} cef_string_utf8_t; + +typedef struct _cef_string_utf16_t { + char16* str; + size_t length; + void (*dtor)(char16* str); +} cef_string_utf16_t; + + +/// +// These functions set string values. If |copy| is true (1) the value will be +// copied instead of referenced. It is up to the user to properly manage +// the lifespan of references. +/// + +CEF_EXPORT int cef_string_wide_set(const wchar_t* src, size_t src_len, + cef_string_wide_t* output, int copy); +CEF_EXPORT int cef_string_utf8_set(const char* src, size_t src_len, + cef_string_utf8_t* output, int copy); +CEF_EXPORT int cef_string_utf16_set(const char16* src, size_t src_len, + cef_string_utf16_t* output, int copy); + + +/// +// Convenience macros for copying values. +/// + +#define cef_string_wide_copy(src, src_len, output) \ + cef_string_wide_set(src, src_len, output, true) +#define cef_string_utf8_copy(src, src_len, output) \ + cef_string_utf8_set(src, src_len, output, true) +#define cef_string_utf16_copy(src, src_len, output) \ + cef_string_utf16_set(src, src_len, output, true) + + +/// +// These functions clear string values. The structure itself is not freed. +/// + +CEF_EXPORT void cef_string_wide_clear(cef_string_wide_t* str); +CEF_EXPORT void cef_string_utf8_clear(cef_string_utf8_t* str); +CEF_EXPORT void cef_string_utf16_clear(cef_string_utf16_t* str); + + +/// +// These functions compare two string values with the same results as strcmp(). +/// + +CEF_EXPORT int cef_string_wide_cmp(const cef_string_wide_t* str1, + const cef_string_wide_t* str2); +CEF_EXPORT int cef_string_utf8_cmp(const cef_string_utf8_t* str1, + const cef_string_utf8_t* str2); +CEF_EXPORT int cef_string_utf16_cmp(const cef_string_utf16_t* str1, + const cef_string_utf16_t* str2); + + +/// +// These functions convert between UTF-8, -16, and -32 strings. They are +// potentially slow so unnecessary conversions should be avoided. The best +// possible result will always be written to |output| with the boolean return +// value indicating whether the conversion is 100% valid. +/// + +CEF_EXPORT int cef_string_wide_to_utf8(const wchar_t* src, size_t src_len, + cef_string_utf8_t* output); +CEF_EXPORT int cef_string_utf8_to_wide(const char* src, size_t src_len, + cef_string_wide_t* output); + +CEF_EXPORT int cef_string_wide_to_utf16(const wchar_t* src, size_t src_len, + cef_string_utf16_t* output); +CEF_EXPORT int cef_string_utf16_to_wide(const char16* src, size_t src_len, + cef_string_wide_t* output); + +CEF_EXPORT int cef_string_utf8_to_utf16(const char* src, size_t src_len, + cef_string_utf16_t* output); +CEF_EXPORT int cef_string_utf16_to_utf8(const char16* src, size_t src_len, + cef_string_utf8_t* output); + + +/// +// These functions convert an ASCII string, typically a hardcoded constant, to a +// Wide/UTF16 string. Use instead of the UTF8 conversion routines if you know +// the string is ASCII. +/// + +CEF_EXPORT int cef_string_ascii_to_wide(const char* src, size_t src_len, + cef_string_wide_t* output); +CEF_EXPORT int cef_string_ascii_to_utf16(const char* src, size_t src_len, + cef_string_utf16_t* output); + + + +/// +// It is sometimes necessary for the system to allocate string structures with +// the expectation that the user will free them. The userfree types act as a +// hint that the user is responsible for freeing the structure. +/// + +typedef cef_string_wide_t* cef_string_userfree_wide_t; +typedef cef_string_utf8_t* cef_string_userfree_utf8_t; +typedef cef_string_utf16_t* cef_string_userfree_utf16_t; + + +/// +// These functions allocate a new string structure. They must be freed by +// calling the associated free function. +/// + +CEF_EXPORT cef_string_userfree_wide_t cef_string_userfree_wide_alloc(); +CEF_EXPORT cef_string_userfree_utf8_t cef_string_userfree_utf8_alloc(); +CEF_EXPORT cef_string_userfree_utf16_t cef_string_userfree_utf16_alloc(); + + +/// +// These functions free the string structure allocated by the associated +// alloc function. Any string contents will first be cleared. +/// + +CEF_EXPORT void cef_string_userfree_wide_free(cef_string_userfree_wide_t str); +CEF_EXPORT void cef_string_userfree_utf8_free(cef_string_userfree_utf8_t str); +CEF_EXPORT void cef_string_userfree_utf16_free(cef_string_userfree_utf16_t str); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ diff --git a/cefpython/cef1/include/internal/cef_string_wrappers.h b/cefpython/cef1/include/internal/cef_string_wrappers.h new file mode 100644 index 00000000..b3012331 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_string_wrappers.h @@ -0,0 +1,712 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ +#pragma once + +#include +#include +#include "include/internal/cef_string_types.h" + +#ifdef BUILDING_CEF_SHARED +#include "base/string16.h" +#endif + + +/// +// Traits implementation for wide character strings. +/// +struct CefStringTraitsWide { + typedef wchar_t char_type; + typedef cef_string_wide_t struct_type; + typedef cef_string_userfree_wide_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_wide_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_wide_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_wide_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_wide_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_wide_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type *s) { + return cef_string_ascii_to_wide(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type *s) { + cef_string_utf8_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_wide_to_utf8(s->str, s->length, &cstr); + std::string str; + if (cstr.length > 0) + str = std::string(cstr.str, cstr.length); + cef_string_utf8_clear(&cstr); + return str; + } + static inline bool from_string(const std::string& str, struct_type *s) { + return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false; + } + static inline std::wstring to_wstring(const struct_type *s) { + return std::wstring(s->str, s->length); + } + static inline bool from_wstring(const std::wstring& str, struct_type *s) { + return cef_string_wide_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#if defined(BUILDING_CEF_SHARED) +#if defined(WCHAR_T_IS_UTF32) + static inline string16 to_string16(const struct_type *s) { + cef_string_utf16_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_wide_to_utf16(s->str, s->length, &cstr); + string16 str; + if (cstr.length > 0) + str = string16(cstr.str, cstr.length); + cef_string_utf16_clear(&cstr); + return str; + } + static inline bool from_string16(const string16& str, struct_type *s) { + return cef_string_utf16_to_wide(str.c_str(), str.length(), s) ? + true : false; + } +#else // WCHAR_T_IS_UTF32 + static inline string16 to_string16(const struct_type *s) { + return string16(s->str, s->length); + } + static inline bool from_string16(const string16& str, struct_type *s) { + return cef_string_wide_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // WCHAR_T_IS_UTF32 +#endif // BUILDING_CEF_SHARED +}; + +/// +// Traits implementation for utf8 character strings. +/// +struct CefStringTraitsUTF8 { + typedef char char_type; + typedef cef_string_utf8_t struct_type; + typedef cef_string_userfree_utf8_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_utf8_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_utf8_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_utf8_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_utf8_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_utf8_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type* s) { + return cef_string_utf8_copy(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type* s) { + return std::string(s->str, s->length); + } + static inline bool from_string(const std::string& str, struct_type* s) { + return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false; + } + static inline std::wstring to_wstring(const struct_type* s) { + cef_string_wide_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf8_to_wide(s->str, s->length, &cstr); + std::wstring str; + if (cstr.length > 0) + str = std::wstring(cstr.str, cstr.length); + cef_string_wide_clear(&cstr); + return str; + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false; + } +#if defined(BUILDING_CEF_SHARED) + static inline string16 to_string16(const struct_type* s) { + cef_string_utf16_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf8_to_utf16(s->str, s->length, &cstr); + string16 str; + if (cstr.length > 0) + str = string16(cstr.str, cstr.length); + cef_string_utf16_clear(&cstr); + return str; + } + static inline bool from_string16(const string16& str, struct_type* s) { + return cef_string_utf16_to_utf8(str.c_str(), str.length(), s) ? + true : false; + } +#endif // BUILDING_CEF_SHARED +}; + +/// +// Traits implementation for utf16 character strings. +/// +struct CefStringTraitsUTF16 { + typedef char16 char_type; + typedef cef_string_utf16_t struct_type; + typedef cef_string_userfree_utf16_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_utf16_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_utf16_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_utf16_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_utf16_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_utf16_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type* s) { + return cef_string_ascii_to_utf16(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type* s) { + cef_string_utf8_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf16_to_utf8(s->str, s->length, &cstr); + std::string str; + if (cstr.length > 0) + str = std::string(cstr.str, cstr.length); + cef_string_utf8_clear(&cstr); + return str; + } + static inline bool from_string(const std::string& str, struct_type* s) { + return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ? + true : false; + } +#if defined(WCHAR_T_IS_UTF32) + static inline std::wstring to_wstring(const struct_type* s) { + cef_string_wide_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf16_to_wide(s->str, s->length, &cstr); + std::wstring str; + if (cstr.length > 0) + str = std::wstring(cstr.str, cstr.length); + cef_string_wide_clear(&cstr); + return str; + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ? + true : false; + } +#else // WCHAR_T_IS_UTF32 + static inline std::wstring to_wstring(const struct_type* s) { + return std::wstring(s->str, s->length); + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // WCHAR_T_IS_UTF32 +#if defined(BUILDING_CEF_SHARED) + static inline string16 to_string16(const struct_type* s) { + return string16(s->str, s->length); + } + static inline bool from_string16(const string16& str, struct_type* s) { + return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // BUILDING_CEF_SHARED +}; + +/// +// CEF string classes can convert between all supported string types. For +// example, the CefStringWide class uses wchar_t as the underlying character +// type and provides two approaches for converting data to/from a UTF8 string +// (std::string). +//

+// 1. Implicit conversion using the assignment operator overload. +//

+//   CefStringWide aCefString;
+//   std::string aUTF8String;
+//   aCefString = aUTF8String; // Assign std::string to CefStringWide
+//   aUTF8String = aCefString; // Assign CefStringWide to std::string
+// 
+// 2. Explicit conversion using the FromString/ToString methods. +//
+//   CefStringWide aCefString;
+//   std::string aUTF8String;
+//   aCefString.FromString(aUTF8String); // Assign std::string to CefStringWide
+//   aUTF8String = aCefString.ToString(); // Assign CefStringWide to std::string
+// 
+// Conversion will only occur if the assigned value is a different string type. +// Assigning a std::string to a CefStringUTF8, for example, will copy the data +// without performing a conversion. +//

+// CEF string classes are safe for reading from multiple threads but not for +// modification. It is the user's responsibility to provide synchronization if +// modifying CEF strings from multiple threads. +/// +template +class CefStringBase { + public: + typedef typename traits::char_type char_type; + typedef typename traits::struct_type struct_type; + typedef typename traits::userfree_struct_type userfree_struct_type; + + /// + // Default constructor. + /// + CefStringBase() : string_(NULL), owner_(false) {} + + /// + // Create a new string from an existing string. Data will always be copied. + /// + CefStringBase(const CefStringBase& str) + : string_(NULL), owner_(false) { + FromString(str.c_str(), str.length(), true); + } + + /// + // Create a new string from an existing std::string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const std::string& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromString(src); + } + CefStringBase(const char* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromString(std::string(src)); + } + + /// + // Create a new string from an existing std::wstring. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const std::wstring& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromWString(src); + } + CefStringBase(const wchar_t* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromWString(std::wstring(src)); + } + +#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) + /// + // Create a new string from an existing string16. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const string16& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromString16(src); + } + CefStringBase(const char16* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromString16(string16(src)); + } +#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 + + /// + // Create a new string from an existing character array. If |copy| is true + // this class will copy the data. Otherwise, this class will reference the + // existing data. Referenced data must exist for the lifetime of this class + // and will not be freed by this class. + /// + CefStringBase(const char_type* src, size_t src_len, bool copy) + : string_(NULL), owner_(false) { + if (src && src_len > 0) + FromString(src, src_len, copy); + } + + /// + // Create a new string referencing an existing string structure without taking + // ownership. Referenced structures must exist for the lifetime of this class + // and will not be freed by this class. + /// + CefStringBase(const struct_type* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (!src) + return; + // Reference the existing structure without taking ownership. + Attach(const_cast(src), false); + } + + virtual ~CefStringBase() { ClearAndFree(); } + + + // The following methods are named for compatibility with the standard library + // string template types. + + /// + // Return a read-only pointer to the string data. + /// + const char_type* c_str() const { return (string_ ? string_->str : NULL); } + + /// + // Return the length of the string data. + /// + size_t length() const { return (string_ ? string_->length : 0); } + + /// + // Return the length of the string data. + /// + inline size_t size() const { return length(); } + + /// + // Returns true if the string is empty. + /// + bool empty() const { return (string_ == NULL || string_->length == 0); } + + /// + // Compare this string to the specified string. + /// + int compare(const CefStringBase& str) const { + if (empty() && str.empty()) + return 0; + if (empty()) + return -1; + if (str.empty()) + return 1; + return traits::compare(string_, str.GetStruct()); + } + + /// + // Clear the string data. + /// + void clear() { + if (string_) + traits::clear(string_); + } + + + // The following methods are unique to CEF string template types. + + /// + // Returns true if this class owns the underlying string structure. + /// + bool IsOwner() const { return owner_; } + + /// + // Returns a read-only pointer to the underlying string structure. May return + // NULL if no structure is currently allocated. + /// + const struct_type* GetStruct() const { return string_; } + + /// + // Returns a writable pointer to the underlying string structure. Will never + // return NULL. + /// + struct_type* GetWritableStruct() { + AllocIfNeeded(); + return string_; + } + + /// + // Clear the state of this class. The underlying string structure and data + // will be freed if this class owns the structure. + /// + void ClearAndFree() { + if (!string_) + return; + if (owner_) { + clear(); + delete string_; + } + string_ = NULL; + owner_ = false; + } + + /// + // Attach to the specified string structure. If |owner| is true this class + // will take ownership of the structure. + /// + void Attach(struct_type* str, bool owner) { + // Free the previous structure and data, if any. + ClearAndFree(); + + string_ = str; + owner_ = owner; + } + + /// + // Take ownership of the specified userfree structure's string data. The + // userfree structure itself will be freed. Only use this method with userfree + // structures. + /// + void AttachToUserFree(userfree_struct_type str) { + // Free the previous structure and data, if any. + ClearAndFree(); + + if (!str) + return; + + AllocIfNeeded(); + owner_ = true; + memcpy(string_, str, sizeof(struct_type)); + + // Free the |str| structure but not the data. + memset(str, 0, sizeof(struct_type)); + traits::userfree_free(str); + } + + /// + // Detach from the underlying string structure. To avoid memory leaks only use + // this method if you already hold a pointer to the underlying string + // structure. + /// + void Detach() { + string_ = NULL; + owner_ = false; + } + + /// + // Create a userfree structure and give it ownership of this class' string + // data. This class will be disassociated from the data. May return NULL if + // this string class currently contains no data. + /// + userfree_struct_type DetachToUserFree() { + if (empty()) + return NULL; + + userfree_struct_type str = traits::userfree_alloc(); + memcpy(str, string_, sizeof(struct_type)); + + // Free this class' structure but not the data. + memset(string_, 0, sizeof(struct_type)); + ClearAndFree(); + + return str; + } + + /// + // Set this string's data to the specified character array. If |copy| is true + // this class will copy the data. Otherwise, this class will reference the + // existing data. Referenced data must exist for the lifetime of this class + // and will not be freed by this class. + /// + bool FromString(const char_type* src, size_t src_len, bool copy) { + if (src == NULL || src_len == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::set(src, src_len, string_, copy) ? true : false; + } + + /// + // Set this string's data from an existing ASCII string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromASCII(const char* str) { + size_t len = str ? strlen(str) : 0; + if (len == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_ascii(str, len, string_); + } + + /// + // Return this string's data as a std::string. Translation will occur if + // necessary based on the underlying string type. + /// + std::string ToString() const { + if (empty()) + return std::string(); + return traits::to_string(string_); + } + + /// + // Set this string's data from an existing std::string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromString(const std::string& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string(str, string_); + } + + /// + // Return this string's data as a std::wstring. Translation will occur if + // necessary based on the underlying string type. + /// + std::wstring ToWString() const { + if (empty()) + return std::wstring(); + return traits::to_wstring(string_); + } + + /// + // Set this string's data from an existing std::wstring. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromWString(const std::wstring& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_wstring(str, string_); + } +#if defined(BUILDING_CEF_SHARED) + /// + // Return this string's data as a string16. Translation will occur if + // necessary based on the underlying string type. + /// + string16 ToString16() const { + if (empty()) + return string16(); + return traits::to_string16(string_); + } + + /// + // Set this string's data from an existing string16. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromString16(const string16& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string16(str, string_); + } +#endif // BUILDING_CEF_SHARED + + /// + // Comparison operator overloads. + /// + bool operator<(const CefStringBase& str) const { + return (compare(str) < 0); + } + bool operator<=(const CefStringBase& str) const { + return (compare(str) <= 0); + } + bool operator>(const CefStringBase& str) const { + return (compare(str) > 0); + } + bool operator>=(const CefStringBase& str) const { + return (compare(str) >= 0); + } + bool operator==(const CefStringBase& str) const { + return (compare(str) == 0); + } + bool operator!=(const CefStringBase& str) const { + return (compare(str) != 0); + } + + /// + // Assignment operator overloads. + /// + CefStringBase& operator=(const CefStringBase& str) { + FromString(str.c_str(), str.length(), true); + return *this; + } + operator std::string() const { + return ToString(); + } + CefStringBase& operator=(const std::string& str) { + FromString(str); + return *this; + } + CefStringBase& operator=(const char* str) { + FromString(std::string(str)); + return *this; + } + operator std::wstring() const { + return ToWString(); + } + CefStringBase& operator=(const std::wstring& str) { + FromWString(str); + return *this; + } + CefStringBase& operator=(const wchar_t* str) { + FromWString(std::wstring(str)); + return *this; + } +#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) + operator string16() const { + return ToString16(); + } + CefStringBase& operator=(const string16& str) { + FromString16(str); + return *this; + } + CefStringBase& operator=(const char16* str) { + FromString16(string16(str)); + return *this; + } +#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 + + private: + // Allocate the string structure if it doesn't already exist. + void AllocIfNeeded() { + if (string_ == NULL) { + string_ = new struct_type; + memset(string_, 0, sizeof(struct_type)); + owner_ = true; + } + } + + struct_type* string_; + bool owner_; +}; + + +typedef CefStringBase CefStringWide; +typedef CefStringBase CefStringUTF8; +typedef CefStringBase CefStringUTF16; + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ diff --git a/cefpython/cef1/include/internal/cef_time.h b/cefpython/cef1/include/internal/cef_time.h new file mode 100644 index 00000000..64e601fe --- /dev/null +++ b/cefpython/cef1/include/internal/cef_time.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TIME_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TIME_H_ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/internal/cef_export.h" +#include + +/// +// Time information. Values should always be in UTC. +/// +typedef struct _cef_time_t { + int year; // Four digit year "2007" + int month; // 1-based month (values 1 = January, etc.) + int day_of_week; // 0-based day of week (0 = Sunday, etc.) + int day_of_month; // 1-based day of month (1-31) + int hour; // Hour within the current day (0-23) + int minute; // Minute within the current hour (0-59) + int second; // Second within the current minute (0-59 plus leap + // seconds which may take it up to 60). + int millisecond; // Milliseconds within the current second (0-999) +} cef_time_t; + +/// +// Converts cef_time_t to/from time_t. Returns true (1) on success and false (0) +// on failure. +/// +CEF_EXPORT int cef_time_to_timet(const cef_time_t* cef_time, time_t* time); +CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time); + +/// +// Converts cef_time_t to/from a double which is the number of seconds since +// epoch (Jan 1, 1970). Webkit uses this format to represent time. A value of 0 +// means "not initialized". Returns true (1) on success and false (0) on +// failure. +/// +CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time); +CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time); + +/// +// Retrieve the current system time. +// +CEF_EXPORT int cef_time_now(cef_time_t* cef_time); + +/// +// Retrieve the delta in milliseconds between two time values. +// +CEF_EXPORT int cef_time_delta(const cef_time_t* cef_time1, + const cef_time_t* cef_time2, + long long* delta); + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_TIME_H_ diff --git a/cefpython/cef1/include/internal/cef_tuple.h b/cefpython/cef1/include/internal/cef_tuple.h new file mode 100644 index 00000000..d9a1a2c9 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_tuple.h @@ -0,0 +1,1082 @@ +// Copyright (c) 2006-2011 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The contents of this file are identical to base/tuple.h + +// A Tuple is a generic templatized container, similar in concept to std::pair. +// There are classes Tuple0 to Tuple6, cooresponding to the number of elements +// it contains. The convenient MakeTuple() function takes 0 to 6 arguments, +// and will construct and return the appropriate Tuple object. The functions +// DispatchToMethod and DispatchToFunction take a function pointer or instance +// and method pointer, and unpack a tuple into arguments to the call. +// +// Tuple elements are copied by value, and stored in the tuple. See the unit +// tests for more details of how/when the values are copied. +// +// Example usage: +// // These two methods of creating a Tuple are identical. +// Tuple2 tuple_a(1, "wee"); +// Tuple2 tuple_b = MakeTuple(1, "wee"); +// +// void SomeFunc(int a, const char* b) { } +// DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") +// DispatchToFunction( +// &SomeFunc, MakeTuple(10, "foo")); // SomeFunc(10, "foo") +// +// struct { void SomeMeth(int a, int b, int c) { } } foo; +// DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3)); +// // foo->SomeMeth(1, 2, 3); + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ +#pragma once + +#if defined(OS_CHROMEOS) +// To troubleshoot crosbug.com/7327. +#include "base/logging.h" +#endif +// Traits ---------------------------------------------------------------------- +// +// A simple traits class for tuple arguments. +// +// ValueType: the bare, nonref version of a type (same as the type for nonrefs). +// RefType: the ref version of a type (same as the type for refs). +// ParamType: what type to pass to functions (refs should not be constified). + +template +struct TupleTraits { + typedef P ValueType; + typedef P& RefType; + typedef const P& ParamType; +}; + +template +struct TupleTraits { + typedef P ValueType; + typedef P& RefType; + typedef P& ParamType; +}; + +template +struct TupleTypes { }; + +// Tuple ----------------------------------------------------------------------- +// +// This set of classes is useful for bundling 0 or more heterogeneous data types +// into a single variable. The advantage of this is that it greatly simplifies +// function objects that need to take an arbitrary number of parameters; see +// RunnableMethod and IPC::MessageWithTuple. +// +// Tuple0 is supplied to act as a 'void' type. It can be used, for example, +// when dispatching to a function that accepts no arguments (see the +// Dispatchers below). +// Tuple1 is rarely useful. One such use is when A is non-const ref that you +// want filled by the dispatchee, and the tuple is merely a container for that +// output (a "tier"). See MakeRefTuple and its usages. + +struct Tuple0 { + typedef Tuple0 ValueTuple; + typedef Tuple0 RefTuple; + typedef Tuple0 ParamTuple; +}; + +template +struct Tuple1 { + public: + typedef A TypeA; + + Tuple1() {} + explicit Tuple1(typename TupleTraits::ParamType a) : a(a) {} + + A a; +}; + +template +struct Tuple2 { + public: + typedef A TypeA; + typedef B TypeB; + + Tuple2() {} + Tuple2(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b) + : a(a), b(b) { + } + + A a; + B b; +}; + +template +struct Tuple3 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + + Tuple3() {} + Tuple3(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c) + : a(a), b(b), c(c) { + } + + A a; + B b; + C c; +}; + +template +struct Tuple4 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + + Tuple4() {} + Tuple4(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d) + : a(a), b(b), c(c), d(d) { + } + + A a; + B b; + C c; + D d; +}; + +template +struct Tuple5 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + + Tuple5() {} + Tuple5(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e) + : a(a), b(b), c(c), d(d), e(e) { + } + + A a; + B b; + C c; + D d; + E e; +}; + +template +struct Tuple6 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + + Tuple6() {} + Tuple6(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f) + : a(a), b(b), c(c), d(d), e(e), f(f) { + } + + A a; + B b; + C c; + D d; + E e; + F f; +}; + +template +struct Tuple7 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + typedef G TypeG; + + Tuple7() {} + Tuple7(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::ParamType g) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g) { + } + + A a; + B b; + C c; + D d; + E e; + F f; + G g; +}; + +template +struct Tuple8 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + typedef G TypeG; + typedef H TypeH; + + Tuple8() {} + Tuple8(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::ParamType g, + typename TupleTraits::ParamType h) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) { + } + + A a; + B b; + C c; + D d; + E e; + F f; + G g; + H h; +}; + +// Tuple types ---------------------------------------------------------------- +// +// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the +// definitions of class types the tuple takes as parameters. + +template <> +struct TupleTypes< Tuple0 > { + typedef Tuple0 ValueTuple; + typedef Tuple0 RefTuple; + typedef Tuple0 ParamTuple; +}; + +template +struct TupleTypes< Tuple1 > { + typedef Tuple1::ValueType> ValueTuple; + typedef Tuple1::RefType> RefTuple; + typedef Tuple1::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple2 > { + typedef Tuple2::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple2::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple2::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple3 > { + typedef Tuple3::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple3::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple3::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple4 > { + typedef Tuple4::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple4::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple4::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple5 > { + typedef Tuple5::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple5::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple5::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple6 > { + typedef Tuple6::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple6::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple6::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple7 > { + typedef Tuple7::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple7::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple7::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple8 > { + typedef Tuple8::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple8::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple8::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +// Tuple creators ------------------------------------------------------------- +// +// Helper functions for constructing tuples while inferring the template +// argument types. + +inline Tuple0 MakeTuple() { + return Tuple0(); +} + +template +inline Tuple1 MakeTuple(const A& a) { + return Tuple1(a); +} + +template +inline Tuple2 MakeTuple(const A& a, const B& b) { + return Tuple2(a, b); +} + +template +inline Tuple3 MakeTuple(const A& a, const B& b, const C& c) { + return Tuple3(a, b, c); +} + +template +inline Tuple4 MakeTuple(const A& a, const B& b, const C& c, + const D& d) { + return Tuple4(a, b, c, d); +} + +template +inline Tuple5 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e) { + return Tuple5(a, b, c, d, e); +} + +template +inline Tuple6 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e, const F& f) { + return Tuple6(a, b, c, d, e, f); +} + +template +inline Tuple7 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e, const F& f, + const G& g) { + return Tuple7(a, b, c, d, e, f, g); +} + +template +inline Tuple8 MakeTuple(const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g, const H& h) { + return Tuple8(a, b, c, d, e, f, g, h); +} + +// The following set of helpers make what Boost refers to as "Tiers" - a tuple +// of references. + +template +inline Tuple1 MakeRefTuple(A& a) { + return Tuple1(a); +} + +template +inline Tuple2 MakeRefTuple(A& a, B& b) { + return Tuple2(a, b); +} + +template +inline Tuple3 MakeRefTuple(A& a, B& b, C& c) { + return Tuple3(a, b, c); +} + +template +inline Tuple4 MakeRefTuple(A& a, B& b, C& c, D& d) { + return Tuple4(a, b, c, d); +} + +template +inline Tuple5 MakeRefTuple(A& a, B& b, C& c, D& d, E& e) { + return Tuple5(a, b, c, d, e); +} + +template +inline Tuple6 MakeRefTuple(A& a, B& b, C& c, D& d, E& e, + F& f) { + return Tuple6(a, b, c, d, e, f); +} + +template +inline Tuple7 MakeRefTuple(A& a, B& b, C& c, D& d, + E& e, F& f, G& g) { + return Tuple7(a, b, c, d, e, f, g); +} + +template +inline Tuple8 MakeRefTuple(A& a, B& b, C& c, + D& d, E& e, F& f, + G& g, H& h) { + return Tuple8(a, b, c, d, e, f, g, h); +} + +// Dispatchers ---------------------------------------------------------------- +// +// Helper functions that call the given method on an object, with the unpacked +// tuple arguments. Notice that they all have the same number of arguments, +// so you need only write: +// DispatchToMethod(object, &Object::method, args); +// This is very useful for templated dispatchers, since they don't need to know +// what type |args| is. + +// Non-Static Dispatchers with no out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) { + (obj->*method)(); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) { + (obj->*method)(arg); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1& arg) { +#if defined(OS_CHROMEOS) + // To troubleshoot crosbug.com/7327. + CHECK(obj); + CHECK(&arg); + CHECK(method); +#endif + (obj->*method)(arg.a); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple2& arg) { + (obj->*method)(arg.a, arg.b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& arg) { + (obj->*method)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple7& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g); +} + +// Static Dispatchers with no out params. + +template +inline void DispatchToFunction(Function function, const Tuple0& arg) { + (*function)(); +} + +template +inline void DispatchToFunction(Function function, const A& arg) { + (*function)(arg); +} + +template +inline void DispatchToFunction(Function function, const Tuple1& arg) { + (*function)(arg.a); +} + +template +inline void DispatchToFunction(Function function, const Tuple2& arg) { + (*function)(arg.a, arg.b); +} + +template +inline void DispatchToFunction(Function function, const Tuple3& arg) { + (*function)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToFunction(Function function, + const Tuple4& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToFunction(Function function, + const Tuple5& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToFunction(Function function, + const Tuple6& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +template +inline void DispatchToFunction(Function function, + const Tuple7& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g); +} + +template +inline void DispatchToFunction(Function function, + const Tuple8& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g, arg.h); +} + +// Dispatchers with 0 out param (as a Tuple0). + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple0& arg, Tuple0*) { + (obj->*method)(); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) { + (obj->*method)(arg); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple1& arg, Tuple0*) { + (obj->*method)(arg.a); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple2& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +// Dispatchers with 1 out param. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple1* out) { + (obj->*method)(&out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple1* out) { + (obj->*method)(in, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple1* out) { + (obj->*method)(in.a, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a); +} + +// Dispatchers with 2 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple2* out) { + (obj->*method)(&out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple2* out) { + (obj->*method)(in, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple2* out) { + (obj->*method)(in.a, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b); +} + +// Dispatchers with 3 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple3* out) { + (obj->*method)(&out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple3* out) { + (obj->*method)(in, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple3* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b, &out->c); +} + +// Dispatchers with 4 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple4* out) { + (obj->*method)(&out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple4* out) { + (obj->*method)(in, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple4* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, + &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, + &out->a, &out->b, &out->c, &out->d); +} + +// Dispatchers with 5 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple5* out) { + (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple5* out) { + (obj->*method)(in, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple5* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d, + &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, + &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, + &out->a, &out->b, &out->c, &out->d, &out->e); +} + +#endif // CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ diff --git a/cefpython/cef1/include/internal/cef_types.h b/cefpython/cef1/include/internal/cef_types.h new file mode 100644 index 00000000..0726b1db --- /dev/null +++ b/cefpython/cef1/include/internal/cef_types.h @@ -0,0 +1,1212 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ +#pragma once + +#include "include/internal/cef_build.h" +#include "include/internal/cef_string.h" +#include "include/internal/cef_string_list.h" +#include "include/internal/cef_time.h" + +// Bring in platform-specific definitions. +#if defined(OS_WIN) +#include "include/internal/cef_types_win.h" +#elif defined(OS_MACOSX) +#include "include/internal/cef_types_mac.h" +#elif defined(OS_LINUX) +#include "include/internal/cef_types_linux.h" +#endif + +#include // For size_t + +// The NSPR system headers define 64-bit as |long| when possible, except on +// Mac OS X. In order to not have typedef mismatches, we do the same on LP64. +// +// On Mac OS X, |long long| is used for 64-bit types for compatibility with +// format macros even in the LP64 model. +#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +typedef long int64; // NOLINT(runtime/int) +typedef unsigned long uint64; // NOLINT(runtime/int) +#else +typedef long long int64; // NOLINT(runtime/int) +typedef unsigned long long uint64; // NOLINT(runtime/int) +#endif + +// TODO: Remove these type guards. These are to avoid conflicts with +// obsolete/protypes.h in the Gecko SDK. +#ifndef _INT32 +#define _INT32 +typedef int int32; +#endif + +// TODO: Remove these type guards. These are to avoid conflicts with +// obsolete/protypes.h in the Gecko SDK. +#ifndef _UINT32 +#define _UINT32 +typedef unsigned int uint32; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// Log severity levels. +/// +enum cef_log_severity_t { + LOGSEVERITY_VERBOSE = -1, + LOGSEVERITY_INFO, + LOGSEVERITY_WARNING, + LOGSEVERITY_ERROR, + LOGSEVERITY_ERROR_REPORT, + // Disables logging completely. + LOGSEVERITY_DISABLE = 99 +}; + +/// +// Initialization settings. Specify NULL or 0 to get the recommended default +// values. +/// +typedef struct _cef_settings_t { + /// + // Size of this structure. + /// + size_t size; + + /// + // Set to true (1) to have the message loop run in a separate thread. If + // false (0) than the CefDoMessageLoopWork() function must be called from + // your application message loop. + /// + bool multi_threaded_message_loop; + + /// + // The location where cache data will be stored on disk. If empty an + // in-memory cache will be used. HTML5 databases such as localStorage will + // only persist across sessions if a cache path is specified. + /// + cef_string_t cache_path; + + /// + // Value that will be returned as the User-Agent HTTP header. If empty the + // default User-Agent string will be used. + /// + cef_string_t user_agent; + + /// + // Value that will be inserted as the product portion of the default + // User-Agent string. If empty the Chromium product version will be used. If + // |userAgent| is specified this value will be ignored. + /// + cef_string_t product_version; + + /// + // The locale string that will be passed to WebKit. If empty the default + // locale of "en-US" will be used. This value is ignored on Linux where locale + // is determined using environment variable parsing with the precedence order: + // LANGUAGE, LC_ALL, LC_MESSAGES and LANG. + /// + cef_string_t locale; + + /// + // List of fully qualified paths to plugins (including plugin name) that will + // be loaded in addition to any plugins found in the default search paths. + /// + cef_string_list_t extra_plugin_paths; + + /// + // The directory and file name to use for the debug log. If empty, the + // default name of "debug.log" will be used and the file will be written + // to the application directory. + /// + cef_string_t log_file; + + /// + // The log severity. Only messages of this severity level or higher will be + // logged. + /// + cef_log_severity_t log_severity; + + /// + // Enable DCHECK in release mode to ease debugging. + /// + bool release_dcheck_enabled; + + /// + // The graphics implementation that CEF will use for rendering GPU accelerated + // content like WebGL, accelerated layers and 3D CSS. + /// + cef_graphics_implementation_t graphics_implementation; + + /// + // Quota limit for localStorage data across all origins. Default size is 5MB. + /// + unsigned int local_storage_quota; + + /// + // Quota limit for sessionStorage data per namespace. Default size is 5MB. + /// + unsigned int session_storage_quota; + + /// + // Custom flags that will be used when initializing the V8 JavaScript engine. + // The consequences of using custom flags may not be well tested. + /// + cef_string_t javascript_flags; + +#if defined(OS_WIN) + /// + // Set to true (1) to use the system proxy resolver on Windows when + // "Automatically detect settings" is checked. This setting is disabled + // by default for performance reasons. + /// + bool auto_detect_proxy_settings_enabled; +#endif + + /// + // The fully qualified path for the resources directory. If this value is + // empty the chrome.pak and/or devtools_resources.pak files must be located in + // the module directory on Windows/Linux or the app bundle Resources directory + // on Mac OS X. + /// + cef_string_t resources_dir_path; + + /// + // The fully qualified path for the locales directory. If this value is empty + // the locales directory must be located in the module directory. This value + // is ignored on Mac OS X where pack files are always loaded from the app + // bundle Resources directory. + /// + cef_string_t locales_dir_path; + + /// + // Set to true (1) to disable loading of pack files for resources and locales. + // A resource bundle handler must be provided for the browser and renderer + // processes via CefApp::GetResourceBundleHandler() if loading of pack files + // is disabled. + /// + bool pack_loading_disabled; + + /// + // The number of stack trace frames to capture for uncaught exceptions. + // Specify a positive value to enable the CefV8ContextHandler:: + // OnUncaughtException() callback. Specify 0 (default value) and + // OnUncaughtException() will not be called. + /// + int uncaught_exception_stack_size; + + /// + // By default CEF V8 references will be invalidated (the IsValid() method will + // return false) after the owning context has been released. This reduces the + // need for external record keeping and avoids crashes due to the use of V8 + // references after the associated context has been released. + // + // CEF currently offers two context safety implementations with different + // performance characteristics. The default implementation (value of 0) uses a + // map of hash values and should provide better performance in situations with + // a small number contexts. The alternate implementation (value of 1) uses a + // hidden value attached to each context and should provide better performance + // in situations with a large number of contexts. + // + // If you need better performance in the creation of V8 references and you + // plan to manually track context lifespan you can disable context safety by + // specifying a value of -1. + /// + int context_safety_implementation; +} cef_settings_t; + +/// +// Browser initialization settings. Specify NULL or 0 to get the recommended +// default values. The consequences of using custom values may not be well +// tested. +/// +typedef struct _cef_browser_settings_t { + /// + // Size of this structure. + /// + size_t size; + + /// + // Disable drag & drop of URLs from other windows. + /// + bool drag_drop_disabled; + + /// + // Disable default navigation resulting from drag & drop of URLs. + /// + bool load_drops_disabled; + + /// + // Disable history back/forward navigation. + /// + bool history_disabled; + + /// + // The number of frames per second (fps) for animation and windowless + // rendering. When window rendering is enabled and the JavaScript + // requestAnimationFrame method is used the browser client area will be + // invalidated at the rate specified. When window rendering is disabled the + // CefRenderHandler::OnPaint() method will be called at the rate specified. + // This value must be between 0 and 90. Specify a value of zero for the + // default frame rate of 30 fps. Changing this value may affect display + // performance and/or CPU usage. + /// + int animation_frame_rate; + + // The below values map to WebPreferences settings. + + /// + // Font settings. + /// + cef_string_t standard_font_family; + cef_string_t fixed_font_family; + cef_string_t serif_font_family; + cef_string_t sans_serif_font_family; + cef_string_t cursive_font_family; + cef_string_t fantasy_font_family; + int default_font_size; + int default_fixed_font_size; + int minimum_font_size; + int minimum_logical_font_size; + + /// + // Set to true (1) to disable loading of fonts from remote sources. + /// + bool remote_fonts_disabled; + + /// + // Default encoding for Web content. If empty "ISO-8859-1" will be used. + /// + cef_string_t default_encoding; + + /// + // Set to true (1) to attempt automatic detection of content encoding. + /// + bool encoding_detector_enabled; + + /// + // Set to true (1) to disable JavaScript. + /// + bool javascript_disabled; + + /// + // Set to true (1) to disallow JavaScript from opening windows. + /// + bool javascript_open_windows_disallowed; + + /// + // Set to true (1) to disallow JavaScript from closing windows. + /// + bool javascript_close_windows_disallowed; + + /// + // Set to true (1) to disallow JavaScript from accessing the clipboard. + /// + bool javascript_access_clipboard_disallowed; + + /// + // Set to true (1) to disable DOM pasting in the editor. DOM pasting also + // depends on |javascript_cannot_access_clipboard| being false (0). + /// + bool dom_paste_disabled; + + /// + // Set to true (1) to enable drawing of the caret position. + /// + bool caret_browsing_enabled; + + /// + // Set to true (1) to disable Java. + /// + bool java_disabled; + + /// + // Set to true (1) to disable plugins. + /// + bool plugins_disabled; + + /// + // Set to true (1) to allow access to all URLs from file URLs. + /// + bool universal_access_from_file_urls_allowed; + + /// + // Set to true (1) to allow access to file URLs from other file URLs. + /// + bool file_access_from_file_urls_allowed; + + /// + // Set to true (1) to allow risky security behavior such as cross-site + // scripting (XSS). Use with extreme care. + /// + bool web_security_disabled; + + /// + // Set to true (1) to enable console warnings about XSS attempts. + /// + bool xss_auditor_enabled; + + /// + // Set to true (1) to suppress the network load of image URLs. A cached + // image will still be rendered if requested. + /// + bool image_load_disabled; + + /// + // Set to true (1) to shrink standalone images to fit the page. + /// + bool shrink_standalone_images_to_fit; + + /// + // Set to true (1) to disable browser backwards compatibility features. + /// + bool site_specific_quirks_disabled; + + /// + // Set to true (1) to disable resize of text areas. + /// + bool text_area_resize_disabled; + + /// + // Set to true (1) to disable use of the page cache. + /// + bool page_cache_disabled; + + /// + // Set to true (1) to not have the tab key advance focus to links. + /// + bool tab_to_links_disabled; + + /// + // Set to true (1) to disable hyperlink pings ( and window.sendPing). + /// + bool hyperlink_auditing_disabled; + + /// + // Set to true (1) to enable the user style sheet for all pages. + /// + bool user_style_sheet_enabled; + + /// + // Location of the user style sheet. This must be a data URL of the form + // "data:text/css;charset=utf-8;base64,csscontent" where "csscontent" is the + // base64 encoded contents of the CSS file. + /// + cef_string_t user_style_sheet_location; + + /// + // Set to true (1) to disable style sheets. + /// + bool author_and_user_styles_disabled; + + /// + // Set to true (1) to disable local storage. + /// + bool local_storage_disabled; + + /// + // Set to true (1) to disable databases. + /// + bool databases_disabled; + + /// + // Set to true (1) to disable application cache. + /// + bool application_cache_disabled; + + /// + // Set to true (1) to disable WebGL. + /// + bool webgl_disabled; + + /// + // Set to true (1) to enable accelerated compositing. This is turned off by + // default because the current in-process GPU implementation does not + // support it correctly. + /// + bool accelerated_compositing_enabled; + + /// + // Set to true (1) to disable accelerated layers. This affects features like + // 3D CSS transforms. + /// + bool accelerated_layers_disabled; + + /// + // Set to true (1) to disable accelerated video. + /// + bool accelerated_video_disabled; + + /// + // Set to true (1) to disable accelerated 2d canvas. + /// + bool accelerated_2d_canvas_disabled; + + /// + // Set to true (1) to disable accelerated filters. + /// + bool accelerated_filters_disabled; + + /// + // Set to true (1) to disable accelerated plugins. + /// + bool accelerated_plugins_disabled; + + /// + // Set to true (1) to disable developer tools (WebKit inspector). + /// + bool developer_tools_disabled; + + /// + // Set to true (1) to enable fullscreen mode. + /// + bool fullscreen_enabled; +} cef_browser_settings_t; + +/// +// URL component parts. +/// +typedef struct _cef_urlparts_t { + /// + // The complete URL specification. + /// + cef_string_t spec; + + /// + // Scheme component not including the colon (e.g., "http"). + /// + cef_string_t scheme; + + /// + // User name component. + /// + cef_string_t username; + + /// + // Password component. + /// + cef_string_t password; + + /// + // Host component. This may be a hostname, an IPv4 address or an IPv6 literal + // surrounded by square brackets (e.g., "[2001:db8::1]"). + /// + cef_string_t host; + + /// + // Port number component. + /// + cef_string_t port; + + /// + // Path component including the first slash following the host. + /// + cef_string_t path; + + /// + // Query string component (i.e., everything following the '?'). + /// + cef_string_t query; +} cef_urlparts_t; + +/// +// Cookie information. +/// +typedef struct _cef_cookie_t { + /// + // The cookie name. + /// + cef_string_t name; + + /// + // The cookie value. + /// + cef_string_t value; + + /// + // If |domain| is empty a host cookie will be created instead of a domain + // cookie. Domain cookies are stored with a leading "." and are visible to + // sub-domains whereas host cookies are not. + /// + cef_string_t domain; + + /// + // If |path| is non-empty only URLs at or below the path will get the cookie + // value. + /// + cef_string_t path; + + /// + // If |secure| is true the cookie will only be sent for HTTPS requests. + /// + bool secure; + + /// + // If |httponly| is true the cookie will only be sent for HTTP requests. + /// + bool httponly; + + /// + // The cookie creation date. This is automatically populated by the system on + // cookie creation. + /// + cef_time_t creation; + + /// + // The cookie last access date. This is automatically populated by the system + // on access. + /// + cef_time_t last_access; + + /// + // The cookie expiration date is only valid if |has_expires| is true. + /// + bool has_expires; + cef_time_t expires; +} cef_cookie_t; + +/// +// Storage types. +/// +enum cef_storage_type_t { + ST_LOCALSTORAGE = 0, + ST_SESSIONSTORAGE, +}; + +/// +// Mouse button types. +/// +enum cef_mouse_button_type_t { + MBT_LEFT = 0, + MBT_MIDDLE, + MBT_RIGHT, +}; + +/// +// Key types. +/// +enum cef_key_type_t { + KT_KEYUP = 0, + KT_KEYDOWN, + KT_CHAR, +}; + +/// +// Various browser navigation types supported by chrome. +/// +enum cef_handler_navtype_t { + NAVTYPE_LINKCLICKED = 0, + NAVTYPE_FORMSUBMITTED, + NAVTYPE_BACKFORWARD, + NAVTYPE_RELOAD, + NAVTYPE_FORMRESUBMITTED, + NAVTYPE_OTHER, + NAVTYPE_LINKDROPPED, +}; + +/// +// Supported error code values. See net\base\net_error_list.h for complete +// descriptions of the error codes. +/// +enum cef_handler_errorcode_t { + ERR_FAILED = -2, + ERR_ABORTED = -3, + ERR_INVALID_ARGUMENT = -4, + ERR_INVALID_HANDLE = -5, + ERR_FILE_NOT_FOUND = -6, + ERR_TIMED_OUT = -7, + ERR_FILE_TOO_BIG = -8, + ERR_UNEXPECTED = -9, + ERR_ACCESS_DENIED = -10, + ERR_NOT_IMPLEMENTED = -11, + ERR_CONNECTION_CLOSED = -100, + ERR_CONNECTION_RESET = -101, + ERR_CONNECTION_REFUSED = -102, + ERR_CONNECTION_ABORTED = -103, + ERR_CONNECTION_FAILED = -104, + ERR_NAME_NOT_RESOLVED = -105, + ERR_INTERNET_DISCONNECTED = -106, + ERR_SSL_PROTOCOL_ERROR = -107, + ERR_ADDRESS_INVALID = -108, + ERR_ADDRESS_UNREACHABLE = -109, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110, + ERR_TUNNEL_CONNECTION_FAILED = -111, + ERR_NO_SSL_VERSIONS_ENABLED = -112, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113, + ERR_SSL_RENEGOTIATION_REQUESTED = -114, + ERR_CERT_COMMON_NAME_INVALID = -200, + ERR_CERT_DATE_INVALID = -201, + ERR_CERT_AUTHORITY_INVALID = -202, + ERR_CERT_CONTAINS_ERRORS = -203, + ERR_CERT_NO_REVOCATION_MECHANISM = -204, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205, + ERR_CERT_REVOKED = -206, + ERR_CERT_INVALID = -207, + ERR_CERT_END = -208, + ERR_INVALID_URL = -300, + ERR_DISALLOWED_URL_SCHEME = -301, + ERR_UNKNOWN_URL_SCHEME = -302, + ERR_TOO_MANY_REDIRECTS = -310, + ERR_UNSAFE_REDIRECT = -311, + ERR_UNSAFE_PORT = -312, + ERR_INVALID_RESPONSE = -320, + ERR_INVALID_CHUNKED_ENCODING = -321, + ERR_METHOD_NOT_SUPPORTED = -322, + ERR_UNEXPECTED_PROXY_AUTH = -323, + ERR_EMPTY_RESPONSE = -324, + ERR_RESPONSE_HEADERS_TOO_BIG = -325, + ERR_CACHE_MISS = -400, + ERR_INSECURE_RESPONSE = -501, +}; + +/// +// "Verb" of a drag-and-drop operation as negotiated between the source and +// destination. These constants match their equivalents in WebCore's +// DragActions.h and should not be renumbered. +/// +enum cef_drag_operations_mask_t { + DRAG_OPERATION_NONE = 0, + DRAG_OPERATION_COPY = 1, + DRAG_OPERATION_LINK = 2, + DRAG_OPERATION_GENERIC = 4, + DRAG_OPERATION_PRIVATE = 8, + DRAG_OPERATION_MOVE = 16, + DRAG_OPERATION_DELETE = 32, + DRAG_OPERATION_EVERY = UINT_MAX +}; + +/// +// V8 access control values. +/// +enum cef_v8_accesscontrol_t { + V8_ACCESS_CONTROL_DEFAULT = 0, + V8_ACCESS_CONTROL_ALL_CAN_READ = 1, + V8_ACCESS_CONTROL_ALL_CAN_WRITE = 1 << 1, + V8_ACCESS_CONTROL_PROHIBITS_OVERWRITING = 1 << 2 +}; + +/// +// V8 property attribute values. +/// +enum cef_v8_propertyattribute_t { + V8_PROPERTY_ATTRIBUTE_NONE = 0, // Writeable, Enumerable, + // Configurable + V8_PROPERTY_ATTRIBUTE_READONLY = 1 << 0, // Not writeable + V8_PROPERTY_ATTRIBUTE_DONTENUM = 1 << 1, // Not enumerable + V8_PROPERTY_ATTRIBUTE_DONTDELETE = 1 << 2 // Not configurable +}; + +/// +// Structure representing menu information. +/// +typedef struct _cef_menu_info_t { + /// + // Values from the cef_handler_menutypebits_t enumeration. + /// + int typeFlags; + + /// + // If window rendering is enabled |x| and |y| will be in screen coordinates. + // Otherwise, |x| and |y| will be in view coordinates. + /// + int x; + int y; + + cef_string_t linkUrl; + cef_string_t imageUrl; + cef_string_t pageUrl; + cef_string_t frameUrl; + cef_string_t selectionText; + cef_string_t misspelledWord; + + /// + // Values from the cef_handler_menucapabilitybits_t enumeration. + /// + int editFlags; + + cef_string_t securityInfo; +} cef_menu_info_t; + +/// +// The cef_menu_info_t typeFlags value will be a combination of the +// following values. +/// +enum cef_menu_typebits_t { + /// + // No node is selected + /// + MENUTYPE_NONE = 0x0, + /// + // The top page is selected + /// + MENUTYPE_PAGE = 0x1, + /// + // A subframe page is selected + /// + MENUTYPE_FRAME = 0x2, + /// + // A link is selected + /// + MENUTYPE_LINK = 0x4, + /// + // An image is selected + /// + MENUTYPE_IMAGE = 0x8, + /// + // There is a textual or mixed selection that is selected + /// + MENUTYPE_SELECTION = 0x10, + /// + // An editable element is selected + /// + MENUTYPE_EDITABLE = 0x20, + /// + // A misspelled word is selected + /// + MENUTYPE_MISSPELLED_WORD = 0x40, + /// + // A video node is selected + /// + MENUTYPE_VIDEO = 0x80, + /// + // A video node is selected + /// + MENUTYPE_AUDIO = 0x100, +}; + +/// +// The cef_menu_info_t editFlags value will be a combination of the +// following values. +/// +enum cef_menu_capabilitybits_t { + // Values from WebContextMenuData::EditFlags in WebContextMenuData.h + MENU_CAN_DO_NONE = 0x0, + MENU_CAN_UNDO = 0x1, + MENU_CAN_REDO = 0x2, + MENU_CAN_CUT = 0x4, + MENU_CAN_COPY = 0x8, + MENU_CAN_PASTE = 0x10, + MENU_CAN_DELETE = 0x20, + MENU_CAN_SELECT_ALL = 0x40, + MENU_CAN_TRANSLATE = 0x80, + // Values unique to CEF + MENU_CAN_GO_FORWARD = 0x10000000, + MENU_CAN_GO_BACK = 0x20000000, +}; + +/// +// Supported menu ID values. +/// +enum cef_menu_id_t { + MENU_ID_NAV_BACK = 10, + MENU_ID_NAV_FORWARD = 11, + MENU_ID_NAV_RELOAD = 12, + MENU_ID_NAV_RELOAD_NOCACHE = 13, + MENU_ID_NAV_STOP = 14, + MENU_ID_UNDO = 20, + MENU_ID_REDO = 21, + MENU_ID_CUT = 22, + MENU_ID_COPY = 23, + MENU_ID_PASTE = 24, + MENU_ID_DELETE = 25, + MENU_ID_SELECTALL = 26, + MENU_ID_PRINT = 30, + MENU_ID_VIEWSOURCE = 31, +}; + +enum cef_paint_element_type_t { + PET_VIEW = 0, + PET_POPUP, +}; + +/// +// Post data elements may represent either bytes or files. +/// +enum cef_postdataelement_type_t { + PDE_TYPE_EMPTY = 0, + PDE_TYPE_BYTES, + PDE_TYPE_FILE, +}; + +enum cef_weburlrequest_flags_t { + WUR_FLAG_NONE = 0, + WUR_FLAG_SKIP_CACHE = 0x1, + WUR_FLAG_ALLOW_CACHED_CREDENTIALS = 0x2, + WUR_FLAG_ALLOW_COOKIES = 0x4, + WUR_FLAG_REPORT_UPLOAD_PROGRESS = 0x8, + WUR_FLAG_REPORT_LOAD_TIMING = 0x10, + WUR_FLAG_REPORT_RAW_HEADERS = 0x20 +}; + +enum cef_weburlrequest_state_t { + WUR_STATE_UNSENT = 0, + WUR_STATE_STARTED = 1, + WUR_STATE_HEADERS_RECEIVED = 2, + WUR_STATE_LOADING = 3, + WUR_STATE_DONE = 4, + WUR_STATE_ERROR = 5, + WUR_STATE_ABORT = 6, +}; + +/// +// Focus sources. +/// +enum cef_handler_focus_source_t { + /// + // The source is explicit navigation via the API (LoadURL(), etc). + /// + FOCUS_SOURCE_NAVIGATION = 0, + /// + // The source is a system-generated focus event. + /// + FOCUS_SOURCE_SYSTEM, + /// + // The source is a child widget of the browser window requesting focus. + /// + FOCUS_SOURCE_WIDGET, +}; + +/// +// Key event types. +/// +enum cef_handler_keyevent_type_t { + KEYEVENT_RAWKEYDOWN = 0, + KEYEVENT_KEYDOWN, + KEYEVENT_KEYUP, + KEYEVENT_CHAR +}; + +/// +// Key event modifiers. +/// +enum cef_handler_keyevent_modifiers_t { + KEY_SHIFT = 1 << 0, + KEY_CTRL = 1 << 1, + KEY_ALT = 1 << 2, + KEY_META = 1 << 3, + KEY_KEYPAD = 1 << 4, // Only used on Mac OS-X +}; + +/// +// Structure representing a rectangle. +/// +typedef struct _cef_rect_t { + int x; + int y; + int width; + int height; +} cef_rect_t; + +/// +// Existing thread IDs. +/// +enum cef_thread_id_t { + TID_UI = 0, + TID_IO = 1, + TID_FILE = 2, +}; + +/// +// Paper type for printing. +/// +enum cef_paper_type_t { + PT_LETTER = 0, + PT_LEGAL, + PT_EXECUTIVE, + PT_A3, + PT_A4, + PT_CUSTOM +}; + +/// +// Paper metric information for printing. +/// +struct cef_paper_metrics { + enum cef_paper_type_t paper_type; + // Length and width needed if paper_type is custom_size + // Units are in inches. + double length; + double width; +}; + +/// +// Paper print margins. +/// +struct cef_print_margins { + // Margin size in inches for left/right/top/bottom (this is content margins). + double left; + double right; + double top; + double bottom; + // Margin size (top/bottom) in inches for header/footer. + double header; + double footer; +}; + +/// +// Page orientation for printing. +/// +enum cef_page_orientation { + PORTRAIT = 0, + LANDSCAPE +}; + +/// +// Printing options. +/// +typedef struct _cef_print_options_t { + enum cef_page_orientation page_orientation; + struct cef_paper_metrics paper_metrics; + struct cef_print_margins paper_margins; +} cef_print_options_t; + +/// +// Supported XML encoding types. The parser supports ASCII, ISO-8859-1, and +// UTF16 (LE and BE) by default. All other types must be translated to UTF8 +// before being passed to the parser. If a BOM is detected and the correct +// decoder is available then that decoder will be used automatically. +/// +enum cef_xml_encoding_type_t { + XML_ENCODING_NONE = 0, + XML_ENCODING_UTF8, + XML_ENCODING_UTF16LE, + XML_ENCODING_UTF16BE, + XML_ENCODING_ASCII, +}; + +/// +// XML node types. +/// +enum cef_xml_node_type_t { + XML_NODE_UNSUPPORTED = 0, + XML_NODE_PROCESSING_INSTRUCTION, + XML_NODE_DOCUMENT_TYPE, + XML_NODE_ELEMENT_START, + XML_NODE_ELEMENT_END, + XML_NODE_ATTRIBUTE, + XML_NODE_TEXT, + XML_NODE_CDATA, + XML_NODE_ENTITY_REFERENCE, + XML_NODE_WHITESPACE, + XML_NODE_COMMENT, +}; + +/// +// Status message types. +/// +enum cef_handler_statustype_t { + STATUSTYPE_TEXT = 0, + STATUSTYPE_MOUSEOVER_URL, + STATUSTYPE_KEYBOARD_FOCUS_URL, +}; + +/// +// Popup window features. +/// +typedef struct _cef_popup_features_t { + int x; + bool xSet; + int y; + bool ySet; + int width; + bool widthSet; + int height; + bool heightSet; + + bool menuBarVisible; + bool statusBarVisible; + bool toolBarVisible; + bool locationBarVisible; + bool scrollbarsVisible; + bool resizable; + + bool fullscreen; + bool dialog; + cef_string_list_t additionalFeatures; +} cef_popup_features_t; + +/// +// DOM document types. +/// +enum cef_dom_document_type_t { + DOM_DOCUMENT_TYPE_UNKNOWN = 0, + DOM_DOCUMENT_TYPE_HTML, + DOM_DOCUMENT_TYPE_XHTML, + DOM_DOCUMENT_TYPE_PLUGIN, +}; + +/// +// DOM event category flags. +/// +enum cef_dom_event_category_t { + DOM_EVENT_CATEGORY_UNKNOWN = 0x0, + DOM_EVENT_CATEGORY_UI = 0x1, + DOM_EVENT_CATEGORY_MOUSE = 0x2, + DOM_EVENT_CATEGORY_MUTATION = 0x4, + DOM_EVENT_CATEGORY_KEYBOARD = 0x8, + DOM_EVENT_CATEGORY_TEXT = 0x10, + DOM_EVENT_CATEGORY_COMPOSITION = 0x20, + DOM_EVENT_CATEGORY_DRAG = 0x40, + DOM_EVENT_CATEGORY_CLIPBOARD = 0x80, + DOM_EVENT_CATEGORY_MESSAGE = 0x100, + DOM_EVENT_CATEGORY_WHEEL = 0x200, + DOM_EVENT_CATEGORY_BEFORE_TEXT_INSERTED = 0x400, + DOM_EVENT_CATEGORY_OVERFLOW = 0x800, + DOM_EVENT_CATEGORY_PAGE_TRANSITION = 0x1000, + DOM_EVENT_CATEGORY_POPSTATE = 0x2000, + DOM_EVENT_CATEGORY_PROGRESS = 0x4000, + DOM_EVENT_CATEGORY_XMLHTTPREQUEST_PROGRESS = 0x8000, + DOM_EVENT_CATEGORY_WEBKIT_ANIMATION = 0x10000, + DOM_EVENT_CATEGORY_WEBKIT_TRANSITION = 0x20000, + DOM_EVENT_CATEGORY_BEFORE_LOAD = 0x40000, +}; + +/// +// DOM event processing phases. +/// +enum cef_dom_event_phase_t { + DOM_EVENT_PHASE_UNKNOWN = 0, + DOM_EVENT_PHASE_CAPTURING, + DOM_EVENT_PHASE_AT_TARGET, + DOM_EVENT_PHASE_BUBBLING, +}; + +/// +// DOM node types. +/// +enum cef_dom_node_type_t { + DOM_NODE_TYPE_UNSUPPORTED = 0, + DOM_NODE_TYPE_ELEMENT, + DOM_NODE_TYPE_ATTRIBUTE, + DOM_NODE_TYPE_TEXT, + DOM_NODE_TYPE_CDATA_SECTION, + DOM_NODE_TYPE_ENTITY_REFERENCE, + DOM_NODE_TYPE_ENTITY, + DOM_NODE_TYPE_PROCESSING_INSTRUCTIONS, + DOM_NODE_TYPE_COMMENT, + DOM_NODE_TYPE_DOCUMENT, + DOM_NODE_TYPE_DOCUMENT_TYPE, + DOM_NODE_TYPE_DOCUMENT_FRAGMENT, + DOM_NODE_TYPE_NOTATION, + DOM_NODE_TYPE_XPATH_NAMESPACE, +}; + +/// +// Proxy types. +/// +enum cef_proxy_type_t { + CEF_PROXY_TYPE_DIRECT = 0, + CEF_PROXY_TYPE_NAMED, + CEF_PROXY_TYPE_PAC_STRING, +}; + +/// +// Proxy information. +/// +typedef struct _cef_proxy_info_t { + enum cef_proxy_type_t proxyType; + cef_string_t proxyList; +} cef_proxy_info_t; + +/// +// Geoposition error codes. +/// +enum cef_geoposition_error_code_t { + GEOPOSITON_ERROR_NONE = 0, + GEOPOSITON_ERROR_PERMISSION_DENIED, + GEOPOSITON_ERROR_POSITION_UNAVAILABLE, + GEOPOSITON_ERROR_TIMEOUT, +}; + +/// +// Structure representing geoposition information. The properties of this +// structure correspond to those of the JavaScript Position object although +// their types may differ. +/// +typedef struct _cef_geoposition_t { + /// + // Latitude in decimal degrees north (WGS84 coordinate frame). + /// + double latitude; + + /// + // Longitude in decimal degrees west (WGS84 coordinate frame). + /// + double longitude; + + /// + // Altitude in meters (above WGS84 datum). + /// + double altitude; + + /// + // Accuracy of horizontal position in meters. + /// + double accuracy; + + /// + // Accuracy of altitude in meters. + /// + double altitude_accuracy; + + /// + // Heading in decimal degrees clockwise from true north. + /// + double heading; + + /// + // Horizontal component of device velocity in meters per second. + /// + double speed; + + /// + // Time of position measurement in miliseconds since Epoch in UTC time. This + // is taken from the host computer's system clock. + /// + cef_time_t timestamp; + + /// + // Error code, see enum above. + /// + cef_geoposition_error_code_t error_code; + + /// + // Human-readable error message. + /// + cef_string_t error_message; +} cef_geoposition_t; + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ diff --git a/cefpython/cef1/include/internal/cef_types_linux.h b/cefpython/cef1/include/internal/cef_types_linux.h new file mode 100644 index 00000000..15966907 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_types_linux.h @@ -0,0 +1,88 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_LINUX) +#include +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Window handle. +#define cef_window_handle_t GtkWidget* +#define cef_cursor_handle_t void* + +/// +// Supported graphics implementations. +/// +enum cef_graphics_implementation_t { + DESKTOP_IN_PROCESS = 0, + DESKTOP_IN_PROCESS_COMMAND_BUFFER, +}; + +/// +// Class representing window information. +/// +typedef struct _cef_window_info_t { + // Pointer for the parent GtkBox widget. + cef_window_handle_t m_ParentWidget; + + // Pointer for the new browser widget. + cef_window_handle_t m_Widget; +} cef_window_info_t; + +/// +// Class representing print context information. +/// +typedef struct _cef_print_info_t { + double m_Scale; +} cef_print_info_t; + +/// +// Class representing key information. +/// +typedef struct _cef_key_info_t { + int key; +} cef_key_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_LINUX + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ diff --git a/cefpython/cef1/include/internal/cef_types_mac.h b/cefpython/cef1/include/internal/cef_types_mac.h new file mode 100644 index 00000000..a10c5401 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_types_mac.h @@ -0,0 +1,116 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_MACOSX) +#include "include/internal/cef_string.h" + +// Window handle. +#ifdef __cplusplus +#ifdef __OBJC__ +@class NSCursor; +@class NSView; +#else +class NSCursor; +struct NSView; +#endif +#define cef_window_handle_t NSView* +#define cef_cursor_handle_t NSCursor* +#else +#define cef_window_handle_t void* +#define cef_cursor_handle_t void* +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// Supported graphics implementations. +/// +enum cef_graphics_implementation_t { + DESKTOP_IN_PROCESS = 0, + DESKTOP_IN_PROCESS_COMMAND_BUFFER, +}; + +/// +// Class representing window information. +/// +typedef struct _cef_window_info_t { + cef_string_t m_windowName; + int m_x; + int m_y; + int m_nWidth; + int m_nHeight; + int m_bHidden; + + // NSView pointer for the parent view. + cef_window_handle_t m_ParentView; + + // If window rendering is disabled no browser window will be created. Set + // |m_ParentView| to the window that will act as the parent for popup menus, + // dialog boxes, etc. + int m_bWindowRenderingDisabled; + + // Set to true to enable transparent painting. + int m_bTransparentPainting; + + // NSView pointer for the new browser view. + cef_window_handle_t m_View; +} cef_window_info_t; + +/// +// Class representing print context information. +/// +typedef struct _cef_print_info_t { + double m_Scale; +} cef_print_info_t; + +/// +// Class representing key information. +/// +typedef struct _cef_key_info_t { + int keyCode; + int character; + int characterNoModifiers; +} cef_key_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_MACOSX + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ diff --git a/cefpython/cef1/include/internal/cef_types_win.h b/cefpython/cef1/include/internal/cef_types_win.h new file mode 100644 index 00000000..9b5e48e5 --- /dev/null +++ b/cefpython/cef1/include/internal/cef_types_win.h @@ -0,0 +1,110 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_WIN) +#include +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Window handle. +#define cef_window_handle_t HWND +#define cef_cursor_handle_t HCURSOR + +/// +// Supported graphics implementations. +/// +enum cef_graphics_implementation_t { + ANGLE_IN_PROCESS = 0, + ANGLE_IN_PROCESS_COMMAND_BUFFER, + DESKTOP_IN_PROCESS, + DESKTOP_IN_PROCESS_COMMAND_BUFFER, +}; + +/// +// Class representing window information. +/// +typedef struct _cef_window_info_t { + // Standard parameters required by CreateWindowEx() + DWORD m_dwExStyle; + cef_string_t m_windowName; + DWORD m_dwStyle; + int m_x; + int m_y; + int m_nWidth; + int m_nHeight; + cef_window_handle_t m_hWndParent; + HMENU m_hMenu; + + // If window rendering is disabled no browser window will be created. Set + // |m_hWndParent| to the window that will act as the parent for popup menus, + // dialog boxes, etc. + BOOL m_bWindowRenderingDisabled; + + // Set to true to enable transparent painting. + BOOL m_bTransparentPainting; + + // Handle for the new browser window. + cef_window_handle_t m_hWnd; +} cef_window_info_t; + +/// +// Class representing print context information. +/// +typedef struct _cef_print_info_t { + HDC m_hDC; + RECT m_Rect; + double m_Scale; +} cef_print_info_t; + +/// +// Class representing key information. +/// +typedef struct _cef_key_info_t { + int key; + BOOL sysChar; + BOOL imeChar; +} cef_key_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_WIN + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ diff --git a/cefpython/cef1/include/internal/cef_types_wrappers.h b/cefpython/cef1/include/internal/cef_types_wrappers.h new file mode 100644 index 00000000..dd27229a --- /dev/null +++ b/cefpython/cef1/include/internal/cef_types_wrappers.h @@ -0,0 +1,687 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ +#pragma once + +#include "include/internal/cef_string.h" +#include "include/internal/cef_string_list.h" +#include "include/internal/cef_types.h" + +/// +// Template class that provides common functionality for CEF structure wrapping. +/// +template +class CefStructBase : public traits::struct_type { + public: + typedef typename traits::struct_type struct_type; + + CefStructBase() : attached_to_(NULL) { + Init(); + } + virtual ~CefStructBase() { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + } + + CefStructBase(const CefStructBase& r) { + Init(); + *this = r; + } + CefStructBase(const struct_type& r) { // NOLINT(runtime/explicit) + Init(); + *this = r; + } + + /// + // Clear this object's values. + /// + void Reset() { + Clear(this); + Init(); + } + + /// + // Attach to the source structure's existing values. DetachTo() can be called + // to insert the values back into the existing structure. + /// + void AttachTo(struct_type& source) { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + + // This object is now attached to the new structure. + attached_to_ = &source; + + // Transfer ownership of the values from the source structure. + memcpy(static_cast(this), &source, sizeof(struct_type)); + } + + /// + // Relinquish ownership of values to the target structure. + /// + void DetachTo(struct_type& target) { + if (attached_to_ != &target) { + // Clear the target structure's values only if we are not currently + // attached to that structure. + Clear(&target); + } + + // Transfer ownership of the values to the target structure. + memcpy(&target, static_cast(this), sizeof(struct_type)); + + // Remove the references from this object. + Init(); + } + + /// + // Set this object's values. If |copy| is true the source structure's values + // will be copied instead of referenced. + /// + void Set(const struct_type& source, bool copy) { + traits::set(&source, this, copy); + } + + CefStructBase& operator=(const CefStructBase& s) { + return operator=(static_cast(s)); + } + + CefStructBase& operator=(const struct_type& s) { + Set(s, true); + return *this; + } + + protected: + void Init() { + memset(static_cast(this), 0, sizeof(struct_type)); + attached_to_ = NULL; + traits::init(this); + } + + static void Clear(struct_type* s) { traits::clear(s); } + + struct_type* attached_to_; +}; + + +struct CefRectTraits { + typedef cef_rect_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing a rectangle. +/// +class CefRect : public CefStructBase { + public: + typedef CefStructBase parent; + + CefRect() : parent() {} + CefRect(const cef_rect_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefRect(const CefRect& r) : parent(r) {} // NOLINT(runtime/explicit) + CefRect(int x, int y, int width, int height) : parent() { + Set(x, y, width, height); + } + + bool IsEmpty() const { return width <= 0 || height <= 0; } + void Set(int x, int y, int width, int height) { + this->x = x, this->y = y, this->width = width, this->height = height; + } +}; + +inline bool operator==(const CefRect& a, const CefRect& b) { + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +} + +inline bool operator!=(const CefRect& a, const CefRect& b) { + return !(a == b); +} + + +struct CefPrintOptionsTraits { + typedef cef_print_options_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing print options. +/// +typedef CefStructBase CefPrintOptions; + + + +struct CefPopupFeaturesTraits { + typedef cef_popup_features_t struct_type; + + static inline void init(struct_type* s) { + s->menuBarVisible = true; + s->statusBarVisible = true; + s->toolBarVisible = true; + s->locationBarVisible = true; + s->scrollbarsVisible = true; + s->resizable = true; + } + + static inline void clear(struct_type* s) { + if (s->additionalFeatures) + cef_string_list_free(s->additionalFeatures); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + if (target->additionalFeatures) + cef_string_list_free(target->additionalFeatures); + target->additionalFeatures = src->additionalFeatures ? + cef_string_list_copy(src->additionalFeatures) : NULL; + + target->x = src->x; + target->xSet = src->xSet; + target->y = src->y; + target->ySet = src->ySet; + target->width = src->width; + target->widthSet = src->widthSet; + target->height = src->height; + target->heightSet = src->heightSet; + target->menuBarVisible = src->menuBarVisible; + target->statusBarVisible = src->statusBarVisible; + target->toolBarVisible = src->toolBarVisible; + target->locationBarVisible = src->locationBarVisible; + target->scrollbarsVisible = src->scrollbarsVisible; + target->resizable = src->resizable; + target->fullscreen = src->fullscreen; + target->dialog = src->dialog; + } +}; + +/// +// Class representing popup window features. +/// +typedef CefStructBase CefPopupFeatures; + + +struct CefSettingsTraits { + typedef cef_settings_t struct_type; + + static inline void init(struct_type* s) { + s->size = sizeof(struct_type); + } + + static inline void clear(struct_type* s) { + cef_string_clear(&s->cache_path); + cef_string_clear(&s->user_agent); + cef_string_clear(&s->product_version); + cef_string_clear(&s->locale); + if (s->extra_plugin_paths) + cef_string_list_free(s->extra_plugin_paths); + cef_string_clear(&s->log_file); + cef_string_clear(&s->javascript_flags); + cef_string_clear(&s->resources_dir_path); + cef_string_clear(&s->locales_dir_path); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->multi_threaded_message_loop = src->multi_threaded_message_loop; + + cef_string_set(src->cache_path.str, src->cache_path.length, + &target->cache_path, copy); + cef_string_set(src->user_agent.str, src->user_agent.length, + &target->user_agent, copy); + cef_string_set(src->product_version.str, src->product_version.length, + &target->product_version, copy); + cef_string_set(src->locale.str, src->locale.length, &target->locale, copy); + + if (target->extra_plugin_paths) + cef_string_list_free(target->extra_plugin_paths); + target->extra_plugin_paths = src->extra_plugin_paths ? + cef_string_list_copy(src->extra_plugin_paths) : NULL; + + cef_string_set(src->log_file.str, src->log_file.length, &target->log_file, + copy); + target->log_severity = src->log_severity; + target->release_dcheck_enabled = src->release_dcheck_enabled; + target->graphics_implementation = src->graphics_implementation; + target->local_storage_quota = src->local_storage_quota; + target->session_storage_quota = src->session_storage_quota; + cef_string_set(src->javascript_flags.str, src->javascript_flags.length, + &target->javascript_flags, copy); + +#if defined(OS_WIN) + target->auto_detect_proxy_settings_enabled = + src->auto_detect_proxy_settings_enabled; +#endif + + cef_string_set(src->resources_dir_path.str, src->resources_dir_path.length, + &target->resources_dir_path, copy); + cef_string_set(src->locales_dir_path.str, src->locales_dir_path.length, + &target->locales_dir_path, copy); + target->pack_loading_disabled = src->pack_loading_disabled; + target->uncaught_exception_stack_size = src->uncaught_exception_stack_size; + target->context_safety_implementation = src->context_safety_implementation; + } +}; + +/// +// Class representing initialization settings. +/// +typedef CefStructBase CefSettings; + + +struct CefBrowserSettingsTraits { + typedef cef_browser_settings_t struct_type; + + static inline void init(struct_type* s) { + s->size = sizeof(struct_type); + } + + static inline void clear(struct_type* s) { + cef_string_clear(&s->standard_font_family); + cef_string_clear(&s->fixed_font_family); + cef_string_clear(&s->serif_font_family); + cef_string_clear(&s->sans_serif_font_family); + cef_string_clear(&s->cursive_font_family); + cef_string_clear(&s->fantasy_font_family); + cef_string_clear(&s->default_encoding); + cef_string_clear(&s->user_style_sheet_location); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->drag_drop_disabled = src->drag_drop_disabled; + target->load_drops_disabled = src->load_drops_disabled; + target->history_disabled = src->history_disabled; + target->animation_frame_rate = src->animation_frame_rate; + + cef_string_set(src->standard_font_family.str, + src->standard_font_family.length, &target->standard_font_family, copy); + cef_string_set(src->fixed_font_family.str, src->fixed_font_family.length, + &target->fixed_font_family, copy); + cef_string_set(src->serif_font_family.str, src->serif_font_family.length, + &target->serif_font_family, copy); + cef_string_set(src->sans_serif_font_family.str, + src->sans_serif_font_family.length, &target->sans_serif_font_family, + copy); + cef_string_set(src->cursive_font_family.str, + src->cursive_font_family.length, &target->cursive_font_family, copy); + cef_string_set(src->fantasy_font_family.str, + src->fantasy_font_family.length, &target->fantasy_font_family, copy); + + target->default_font_size = src->default_font_size; + target->default_fixed_font_size = src->default_fixed_font_size; + target->minimum_font_size = src->minimum_font_size; + target->minimum_logical_font_size = src->minimum_logical_font_size; + target->remote_fonts_disabled = src->remote_fonts_disabled; + + cef_string_set(src->default_encoding.str, src->default_encoding.length, + &target->default_encoding, copy); + + target->encoding_detector_enabled = src->encoding_detector_enabled; + target->javascript_disabled = src->javascript_disabled; + target->javascript_open_windows_disallowed = + src->javascript_open_windows_disallowed; + target->javascript_close_windows_disallowed = + src->javascript_close_windows_disallowed; + target->javascript_access_clipboard_disallowed = + src->javascript_access_clipboard_disallowed; + target->dom_paste_disabled = src->dom_paste_disabled; + target->caret_browsing_enabled = src->caret_browsing_enabled; + target->java_disabled = src->java_disabled; + target->plugins_disabled = src->plugins_disabled; + target->universal_access_from_file_urls_allowed = + src->universal_access_from_file_urls_allowed; + target->file_access_from_file_urls_allowed = + src->file_access_from_file_urls_allowed; + target->web_security_disabled = src->web_security_disabled; + target->xss_auditor_enabled = src->xss_auditor_enabled; + target->image_load_disabled = src->image_load_disabled; + target->shrink_standalone_images_to_fit = + src->shrink_standalone_images_to_fit; + target->site_specific_quirks_disabled = src->site_specific_quirks_disabled; + target->text_area_resize_disabled = src->text_area_resize_disabled; + target->page_cache_disabled = src->page_cache_disabled; + target->tab_to_links_disabled = src->tab_to_links_disabled; + target->hyperlink_auditing_disabled = src->hyperlink_auditing_disabled; + target->user_style_sheet_enabled = src->user_style_sheet_enabled; + + cef_string_set(src->user_style_sheet_location.str, + src->user_style_sheet_location.length, + &target->user_style_sheet_location, copy); + + target->author_and_user_styles_disabled = + src->author_and_user_styles_disabled; + target->local_storage_disabled = src->local_storage_disabled; + target->databases_disabled = src->databases_disabled; + target->application_cache_disabled = src->application_cache_disabled; + target->webgl_disabled = src->webgl_disabled; + target->accelerated_compositing_enabled = + src->accelerated_compositing_enabled; + target->accelerated_layers_disabled = src->accelerated_layers_disabled; + target->accelerated_video_disabled = src->accelerated_video_disabled; + target->accelerated_2d_canvas_disabled = + src->accelerated_2d_canvas_disabled; + target->accelerated_filters_disabled = src->accelerated_filters_disabled; + target->accelerated_plugins_disabled = src->accelerated_plugins_disabled; + target->developer_tools_disabled = src->developer_tools_disabled; + target->fullscreen_enabled = src->fullscreen_enabled; + } +}; + +/// +// Class representing browser initialization settings. +/// +typedef CefStructBase CefBrowserSettings; + + +struct CefURLPartsTraits { + typedef cef_urlparts_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->spec); + cef_string_clear(&s->scheme); + cef_string_clear(&s->username); + cef_string_clear(&s->password); + cef_string_clear(&s->host); + cef_string_clear(&s->port); + cef_string_clear(&s->path); + cef_string_clear(&s->query); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + cef_string_set(src->spec.str, src->spec.length, &target->spec, copy); + cef_string_set(src->scheme.str, src->scheme.length, &target->scheme, copy); + cef_string_set(src->username.str, src->username.length, &target->username, + copy); + cef_string_set(src->password.str, src->password.length, &target->password, + copy); + cef_string_set(src->host.str, src->host.length, &target->host, copy); + cef_string_set(src->port.str, src->port.length, &target->port, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + cef_string_set(src->query.str, src->query.length, &target->query, copy); + } +}; + +/// +// Class representing a URL's component parts. +/// +typedef CefStructBase CefURLParts; + + +struct CefTimeTraits { + typedef cef_time_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing a time. +/// +class CefTime : public CefStructBase { + public: + typedef CefStructBase parent; + + CefTime() : parent() {} + CefTime(const cef_time_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefTime(const CefTime& r) : parent(r) {} // NOLINT(runtime/explicit) + explicit CefTime(time_t r) : parent() { SetTimeT(r); } + explicit CefTime(double r) : parent() { SetDoubleT(r); } + + // Converts to/from time_t. + void SetTimeT(time_t r) { + cef_time_from_timet(r, this); + } + time_t GetTimeT() const { + time_t time = 0; + cef_time_to_timet(this, &time); + return time; + } + + // Converts to/from a double which is the number of seconds since epoch + // (Jan 1, 1970). Webkit uses this format to represent time. A value of 0 + // means "not initialized". + void SetDoubleT(double r) { + cef_time_from_doublet(r, this); + } + double GetDoubleT() const { + double time = 0; + cef_time_to_doublet(this, &time); + return time; + } + + // Set this object to now. + void Now() { + cef_time_now(this); + } + + // Return the delta between this object and |other| in milliseconds. + long long Delta(const CefTime& other) { + long long delta = 0; + cef_time_delta(this, &other, &delta); + return delta; + } +}; + + +struct CefCookieTraits { + typedef cef_cookie_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->name); + cef_string_clear(&s->value); + cef_string_clear(&s->domain); + cef_string_clear(&s->path); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + cef_string_set(src->name.str, src->name.length, &target->name, copy); + cef_string_set(src->value.str, src->value.length, &target->value, copy); + cef_string_set(src->domain.str, src->domain.length, &target->domain, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + target->secure = src->secure; + target->httponly = src->httponly; + target->creation = src->creation; + target->last_access = src->last_access; + target->has_expires = src->has_expires; + target->expires = src->expires; + } +}; + +/// +// Class representing a cookie. +/// +typedef CefStructBase CefCookie; + + +struct CefMenuInfoTraits { + typedef cef_menu_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->linkUrl); + cef_string_clear(&s->imageUrl); + cef_string_clear(&s->pageUrl); + cef_string_clear(&s->frameUrl); + cef_string_clear(&s->selectionText); + cef_string_clear(&s->misspelledWord); + cef_string_clear(&s->securityInfo); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->typeFlags = src->typeFlags; + target->x = src->x; + target->y = src->y; + + cef_string_set(src->linkUrl.str, src->linkUrl.length, + &target->linkUrl, copy); + cef_string_set(src->imageUrl.str, src->imageUrl.length, + &target->imageUrl, copy); + cef_string_set(src->pageUrl.str, src->pageUrl.length, + &target->pageUrl, copy); + cef_string_set(src->frameUrl.str, src->frameUrl.length, + &target->frameUrl, copy); + cef_string_set(src->selectionText.str, src->selectionText.length, + &target->selectionText, copy); + cef_string_set(src->misspelledWord.str, src->misspelledWord.length, + &target->misspelledWord, copy); + cef_string_set(src->securityInfo.str, src->securityInfo.length, + &target->securityInfo, copy); + + target->editFlags = src->editFlags; + } +}; + +/// +// Class representing menu info. +/// +typedef CefStructBase CefMenuInfo; + + +struct CefProxyInfoTraits { + typedef cef_proxy_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->proxyList); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->proxyType = src->proxyType; + cef_string_set(src->proxyList.str, src->proxyList.length, + &target->proxyList, copy); + } +}; + +/// +// Class representing the results of proxy resolution. +/// +class CefProxyInfo : public CefStructBase { + public: + /// + // Use a direction connection instead of a proxy. + /// + void UseDirect() { + proxyType = CEF_PROXY_TYPE_DIRECT; + } + + /// + // Use one or more named proxy servers specified in WinHTTP format. Each proxy + // server is of the form: + // + // ["://"][":"] + // + // Multiple values may be separated by semicolons or whitespace. For example, + // "foo1:80;foo2:80". + /// + void UseNamedProxy(const CefString& proxy_uri_list) { + proxyType = CEF_PROXY_TYPE_NAMED; + (CefString(&proxyList)) = proxy_uri_list; + } + + /// + // Use one or more named proxy servers specified in PAC script format. For + // example, "PROXY foobar:99; SOCKS fml:2; DIRECT". + /// + void UsePacString(const CefString& pac_string) { + proxyType = CEF_PROXY_TYPE_PAC_STRING; + (CefString(&proxyList)) = pac_string; + } + + bool IsDirect() const { return proxyType == CEF_PROXY_TYPE_DIRECT; } + bool IsNamedProxy() const { return proxyType == CEF_PROXY_TYPE_NAMED; } + bool IsPacString() const { return proxyType == CEF_PROXY_TYPE_PAC_STRING; } + + CefString ProxyList() const { return CefString(&proxyList); } +}; + + +struct CefGeopositionTraits { + typedef cef_geoposition_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->error_message); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->latitude = src->latitude; + target->longitude = src->longitude; + target->altitude = src->altitude; + target->accuracy = src->accuracy; + target->altitude_accuracy = src->altitude_accuracy; + target->heading = src->heading; + target->speed = src->speed; + target->timestamp = src->timestamp; + target->error_code = src->error_code; + cef_string_set(src->error_message.str, src->error_message.length, + &target->error_message, copy); + } +}; + +/// +// Class representing a geoposition. +/// +typedef CefStructBase CefGeoposition; + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ diff --git a/cefpython/cef1/include/internal/cef_win.h b/cefpython/cef1/include/internal/cef_win.h new file mode 100644 index 00000000..68d91dce --- /dev/null +++ b/cefpython/cef1/include/internal/cef_win.h @@ -0,0 +1,186 @@ +// Copyright (c) 2008 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_WIN_H_ +#define CEF_INCLUDE_INTERNAL_CEF_WIN_H_ +#pragma once + +#if defined(OS_WIN) +#include +#include "include/internal/cef_types_win.h" +#include "include/internal/cef_types_wrappers.h" + +/// +// Atomic increment and decrement. +/// +#define CefAtomicIncrement(p) InterlockedIncrement(p) +#define CefAtomicDecrement(p) InterlockedDecrement(p) + +/// +// Critical section wrapper. +/// +class CefCriticalSection { + public: + CefCriticalSection() { + memset(&m_sec, 0, sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(&m_sec); + } + virtual ~CefCriticalSection() { + DeleteCriticalSection(&m_sec); + } + void Lock() { + EnterCriticalSection(&m_sec); + } + void Unlock() { + LeaveCriticalSection(&m_sec); + } + + CRITICAL_SECTION m_sec; +}; + +/// +// Handle types. +/// +#define CefWindowHandle cef_window_handle_t +#define CefCursorHandle cef_cursor_handle_t + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->m_windowName); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_dwExStyle = src->m_dwExStyle; + cef_string_set(src->m_windowName.str, src->m_windowName.length, + &target->m_windowName, copy); + target->m_dwStyle = src->m_dwStyle; + target->m_x = src->m_x; + target->m_y = src->m_y; + target->m_nWidth = src->m_nWidth; + target->m_nHeight = src->m_nHeight; + target->m_hWndParent = src->m_hWndParent; + target->m_hMenu = src->m_hMenu; + target->m_bWindowRenderingDisabled = src->m_bWindowRenderingDisabled; + target->m_bTransparentPainting = src->m_bTransparentPainting; + target->m_hWnd = src->m_hWnd; + } +}; + +/// +// Class representing window information. +/// +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(HWND hWndParent, RECT windowRect) { + m_dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP | + WS_VISIBLE; + m_hWndParent = hWndParent; + m_x = windowRect.left; + m_y = windowRect.top; + m_nWidth = windowRect.right - windowRect.left; + m_nHeight = windowRect.bottom - windowRect.top; + } + + void SetAsPopup(HWND hWndParent, const CefString& windowName) { + m_dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | + WS_VISIBLE; + m_hWndParent = hWndParent; + m_x = CW_USEDEFAULT; + m_y = CW_USEDEFAULT; + m_nWidth = CW_USEDEFAULT; + m_nHeight = CW_USEDEFAULT; + + cef_string_copy(windowName.c_str(), windowName.length(), &m_windowName); + } + + void SetAsOffScreen(HWND hWndParent) { + m_bWindowRenderingDisabled = TRUE; + m_hWndParent = hWndParent; + } + + void SetTransparentPainting(BOOL transparentPainting) { + m_bTransparentPainting = transparentPainting; + } +}; + + +struct CefPrintInfoTraits { + typedef cef_print_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->m_hDC = src->m_hDC; + target->m_Rect = src->m_Rect; + target->m_Scale = src->m_Scale; + } +}; + +/// +// Class representing print context information. +/// +typedef CefStructBase CefPrintInfo; + + +struct CefKeyInfoTraits { + typedef cef_key_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->key = src->key; + target->sysChar = src->sysChar; + target->imeChar = src->imeChar; + } +}; + +/// +// Class representing key information. +/// +typedef CefStructBase CefKeyInfo; + +#endif // OS_WIN + +#endif // CEF_INCLUDE_INTERNAL_CEF_WIN_H_ diff --git a/cefpython/cef1/include/wrapper/cef_byte_read_handler.h b/cefpython/cef1/include/wrapper/cef_byte_read_handler.h new file mode 100644 index 00000000..f7ca7a15 --- /dev/null +++ b/cefpython/cef1/include/wrapper/cef_byte_read_handler.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ +#define CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Thread safe implementation of the CefReadHandler class for reading an +// in-memory array of bytes. +/// +class CefByteReadHandler : public CefReadHandler { + public: + /// + // Create a new object for reading an array of bytes. An optional |source| + // reference can be kept to keep the underlying data source from being + // released while the reader exists. + /// + CefByteReadHandler(const unsigned char* bytes, size_t size, + CefRefPtr source); + + /// + // Read raw binary data. + /// + virtual size_t Read(void* ptr, size_t size, size_t n); + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. + /// + virtual int Seek(int64 offset, int whence); + + /// + // Return the current offset position. + /// + virtual int64 Tell(); + + /// + // Return non-zero if at end of file. + /// + virtual int Eof(); + + private: + const unsigned char* bytes_; + int64 size_; + int64 offset_; + CefRefPtr source_; + + IMPLEMENT_REFCOUNTING(CefByteReadHandler); + IMPLEMENT_LOCKING(CefByteReadHandler); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ diff --git a/cefpython/cef1/include/wrapper/cef_xml_object.h b/cefpython/cef1/include/wrapper/cef_xml_object.h new file mode 100644 index 00000000..d9f706fd --- /dev/null +++ b/cefpython/cef1/include/wrapper/cef_xml_object.h @@ -0,0 +1,188 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ +#define CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_xml_reader.h" +#include +#include + +class CefStreamReader; + +/// +// Thread safe class for representing XML data as a structured object. This +// class should not be used with large XML documents because all data will be +// resident in memory at the same time. This implementation supports a +// restricted set of XML features: +//
+// (1) Processing instructions, whitespace and comments are ignored.
+// (2) Elements and attributes must always be referenced using the fully
+//     qualified name (ie, namespace:localname).
+// (3) Empty elements () and elements with zero-length values ()
+//     are considered the same.
+// (4) Element nodes are considered part of a value if:
+//     (a) The element node follows a non-element node at the same depth
+//         (see 5), or
+//     (b) The element node does not have a namespace and the parent node does.
+// (5) Mixed node types at the same depth are combined into a single element
+//     value as follows:
+//     (a) All node values are concatenated to form a single string value.
+//     (b) Entity reference nodes are resolved to the corresponding entity
+//         value.
+//     (c) Element nodes are represented by their outer XML string.
+// 
+/// +class CefXmlObject : public CefBase { + public: + typedef std::vector > ObjectVector; + typedef std::map AttributeMap; + + /// + // Create a new object with the specified name. An object name must always be + // at least one character long. + /// + explicit CefXmlObject(const CefString& name); + virtual ~CefXmlObject(); + + /// + // Load the contents of the specified XML stream into this object. The + // existing children and attributes, if any, will first be cleared. + /// + bool Load(CefRefPtr stream, + CefXmlReader::EncodingType encodingType, + const CefString& URI, CefString* loadError); + + /// + // Set the name, children and attributes of this object to a duplicate of the + // specified object's contents. The existing children and attributes, if any, + // will first be cleared. + /// + void Set(CefRefPtr object); + + /// + // Append a duplicate of the children and attributes of the specified object + // to this object. If |overwriteAttributes| is true then any attributes in + // this object that also exist in the specified object will be overwritten + // with the new values. The name of this object is not changed. + /// + void Append(CefRefPtr object, bool overwriteAttributes); + + /// + // Return a new object with the same name, children and attributes as this + // object. The parent of the new object will be NULL. + /// + CefRefPtr Duplicate(); + + /// + // Clears this object's children and attributes. The name and parenting of + // this object are not changed. + /// + void Clear(); + + /// + // Access the object's name. An object name must always be at least one + // character long. + /// + CefString GetName(); + bool SetName(const CefString& name); + + /// + // Access the object's parent. The parent can be NULL if this object has not + // been added as the child on another object. + /// + bool HasParent(); + CefRefPtr GetParent(); + + /// + // Access the object's value. An object cannot have a value if it also has + // children. Attempting to set the value while children exist will fail. + /// + bool HasValue(); + CefString GetValue(); + bool SetValue(const CefString& value); + + /// + // Access the object's attributes. Attributes must have unique names. + /// + bool HasAttributes(); + size_t GetAttributeCount(); + bool HasAttribute(const CefString& name); + CefString GetAttributeValue(const CefString& name); + bool SetAttributeValue(const CefString& name, const CefString& value); + size_t GetAttributes(AttributeMap& attributes); + void ClearAttributes(); + + /// + // Access the object's children. Each object can only have one parent so + // attempting to add an object that already has a parent will fail. Removing a + // child will set the child's parent to NULL. Adding a child will set the + // child's parent to this object. This object's value, if any, will be cleared + // if a child is added. + /// + bool HasChildren(); + size_t GetChildCount(); + bool HasChild(CefRefPtr child); + bool AddChild(CefRefPtr child); + bool RemoveChild(CefRefPtr child); + size_t GetChildren(ObjectVector& children); + void ClearChildren(); + + /// + // Find the first child with the specified name. + /// + CefRefPtr FindChild(const CefString& name); + + /// + // Find all children with the specified name. + /// + size_t FindChildren(const CefString& name, ObjectVector& children); + + private: + void SetParent(CefXmlObject* parent); + + CefString name_; + CefXmlObject* parent_; + CefString value_; + AttributeMap attributes_; + ObjectVector children_; + + IMPLEMENT_REFCOUNTING(CefXmlObject); + IMPLEMENT_LOCKING(CefXmlObject); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ diff --git a/cefpython/cef1/include/wrapper/cef_zip_archive.h b/cefpython/cef1/include/wrapper/cef_zip_archive.h new file mode 100644 index 00000000..b58dbca0 --- /dev/null +++ b/cefpython/cef1/include/wrapper/cef_zip_archive.h @@ -0,0 +1,132 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ +#define CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ +#pragma once + +#include "include/cef_base.h" +#include + +class CefStreamReader; + +/// +// Thread-safe class for accessing zip archive file contents. This class should +// not be used with large archive files because all data will be resident in +// memory at the same time. This implementation supports a restricted set of zip +// archive features: +// (1) Password-protected files are not supported. +// (2) All file names are stored and compared in lower case. +// (3) File ordering from the original zip archive is not maintained. This +// means that files from the same folder may not be located together in the +// file content map. +/// +class CefZipArchive : public CefBase { + public: + /// + // Class representing a file in the archive. Accessing the file data from + // multiple threads is safe provided a reference to the File object is kept. + /// + class File : public CefBase { + public: + /// + // Returns the read-only data contained in the file. + /// + virtual const unsigned char* GetData() =0; + + /// + // Returns the size of the data in the file. + /// + virtual size_t GetDataSize() =0; + + /// + // Returns a CefStreamReader object for streaming the contents of the file. + /// + virtual CefRefPtr GetStreamReader() =0; + }; + typedef std::map > FileMap; + + /// + // Create a new object. + /// + CefZipArchive(); + virtual ~CefZipArchive(); + + /// + // Load the contents of the specified zip archive stream into this object. + // If |overwriteExisting| is true then any files in this object that also + // exist in the specified archive will be replaced with the new files. + // Returns the number of files successfully loaded. + /// + size_t Load(CefRefPtr stream, bool overwriteExisting); + + /// + // Clears the contents of this object. + /// + void Clear(); + + /// + // Returns the number of files in the archive. + /// + size_t GetFileCount(); + + /// + // Returns true if the specified file exists and has contents. + /// + bool HasFile(const CefString& fileName); + + /// + // Returns the specified file. + /// + CefRefPtr GetFile(const CefString& fileName); + + /// + // Removes the specified file. + /// + bool RemoveFile(const CefString& fileName); + + /// + // Returns the map of all files. + /// + size_t GetFiles(FileMap& map); + + private: + FileMap contents_; + + IMPLEMENT_REFCOUNTING(CefZipArchive); + IMPLEMENT_LOCKING(CefZipArchive); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ diff --git a/cefpython/cef1/linux/CEF-GTK-patch.txt b/cefpython/cef1/linux/CEF-GTK-patch.txt new file mode 100644 index 00000000..fba8f3a1 --- /dev/null +++ b/cefpython/cef1/linux/CEF-GTK-patch.txt @@ -0,0 +1,54 @@ +See this topic on the CEF C++ forum for more details: +http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10641 + +Do the following changes in the CEF C++ sources: + +1. In `chromium/src/cef/libcef/browser_impl_gtk.cc`: + + At the end of the CefBrowserImpl::UIT_CreateBrowser() function, + before the return statement add the following code: + + gtk_widget_show_all(GTK_WIDGET(window_info_.m_Widget)); + +2. In `chromium/src/cef/libcef/webwidget_host_gtk.cc`: + + In WebWidgetHostGtkWidget::CreateNewWidget() function replace this line: + + gtk_box_pack_start(GTK_BOX(parent_view), widget, TRUE, TRUE, 0); + + With the following code: + + if (GTK_IS_BOX(parent_view)) { + gtk_box_pack_start(GTK_BOX(parent_view), widget, TRUE, TRUE, 0); + } else { + // Parent view shouldn't contain any children, but in wxWidgets library + // there will be GtkPizza widget for Panel or any other control. + GList *children, *iter; + children = gtk_container_get_children(GTK_CONTAINER(parent_view)); + GtkWidget* child = NULL; + GtkWidget* vbox = gtk_vbox_new(FALSE, 0); + for (iter = children; iter != NULL; iter = g_list_next(iter)) { + child = GTK_WIDGET(iter->data); + // We will have to keep a reference to that child that we remove, + // otherwise we will get lots of warnings like "invalid unclassed + // pointer in cast to `GtkPizza'". First we increase a reference, + // we need to do this for a moment before we add this child to the + // vbox, then we will decrease that reference. + g_object_ref(G_OBJECT(child)); + gtk_container_remove(GTK_CONTAINER(parent_view), child); + } + g_list_free(children); + gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0); + if (child != NULL) { + // This child is packed to the box only so that its reference lives, + // as it might be referenced from other code thus resulting in errors. + gtk_box_pack_end(GTK_BOX(vbox), child, FALSE, FALSE, 0); + gtk_widget_hide(GTK_WIDGET(child)); + g_object_unref(G_OBJECT(child)); + } + gtk_widget_show(GTK_WIDGET(vbox)); + if (GTK_IS_SCROLLED_WINDOW(parent_view)) + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(parent_view), vbox); + else + gtk_container_add(GTK_CONTAINER(parent_view), vbox); + } diff --git a/cefpython/cef1/linux/binaries_32bit/LICENSE.txt b/cefpython/cef1/linux/binaries_32bit/LICENSE.txt new file mode 100644 index 00000000..97f1e961 --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/LICENSE.txt @@ -0,0 +1,36 @@ +Copyright (c) 2012-2013 Czarek Tomczak. Portions Copyright +(c) 2008-2013 Marshall A.Greenblatt, 2006-2009 Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef1/linux/binaries_32bit/cefclient b/cefpython/cef1/linux/binaries_32bit/cefclient new file mode 100755 index 00000000..c11fc0bc Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/cefclient differ diff --git a/cefpython/cef1/linux/binaries_32bit/cefpython_py27.py b/cefpython/cef1/linux/binaries_32bit/cefpython_py27.py new file mode 100644 index 00000000..0b0e988c --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/cefpython_py27.py @@ -0,0 +1,815 @@ +# This file contains API for the "cefpython.pyd" module, all functions are dummy. +# Use it as a quick reference. Use it for code completion in your IDE. +# This file does NOT need to be distribitued along with binaries. + +raise Exception("A dummy API file was imported instead of the PYD module.") + +""" +Detailed documentation with examples can be found on wiki pages: +http://code.google.com/p/cefpython/w/list +""" + +# Global functions in cefpython module. + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl): + return Browser() + +def FormatJavascriptStackTrace(stackTrace): + return "" + +def GetBrowserByWindowHandle(windowHandle): + return Browser() + +def GetJavascriptStackTrace(frameLimit=100): + return [] + +def Initialize(applicationSettings={}): + return None + +def IsKeyModifier(key, modifiers): + return False + +def MessageLoop(): + return None + +def MessageLoopWork(): + return None + +def QuitMessageLoop(): + return None + +def Shutdown(): + return None + +def GetModuleDirectory(): + return "" + +# +# Settings +# + +# Values are dummy, these are NOT the defaults. +ApplicationSettings = { + "auto_detect_proxy_settings_enabled": False, + "cache_path": "", + "extra_plugin_paths": [""], + "graphics_implementation": ANGLE_IN_PROCESS, + "javascript_flags": "", + "local_storage_quota": 5*1024*1024, + "locale": "", + "locales_dir_path": "", + "log_file": "", + "log_severity": LOGSEVERITY_INFO, + "release_dcheck_enabled": False, + "multi_threaded_message_loop": False, + "pack_loading_disabled": False, + "product_version": "", + "resources_dir_path": "", + "session_storage_quota": 5*1024*1024, + "string_encoding": "utf-8", + "uncaught_exception_stack_size": 0, + "user_agent": "", +} + +# ApplicationSettings["log_severity"] +LOGSEVERITY_VERBOSE = 0 +LOGSEVERITY_INFO = 0 +LOGSEVERITY_WARNING = 0 +LOGSEVERITY_ERROR = 0 +LOGSEVERITY_ERROR_REPORT = 0 +LOGSEVERITY_DISABLE = 0 + +# ApplicationSettings["graphics_implementation"] +ANGLE_IN_PROCESS = 0 +ANGLE_IN_PROCESS_COMMAND_BUFFER = 0 +DESKTOP_IN_PROCESS = 0 +DESKTOP_IN_PROCESS_COMMAND_BUFFER = 0 + +# Values are dummy, these are NOT the defaults. +BrowserSettings = { + "accelerated_2d_canvas_disabled": False, + "accelerated_compositing_enabled": False, + "accelerated_filters_disabled": False, + "accelerated_layers_disabled": False, + "accelerated_plugins_disabled": False, + "accelerated_video_disabled": False, + "animation_frame_rate": 0, + "application_cache_disabled": False, + "author_and_user_styles_disabled": False, + "caret_browsing_enabled": False, + "cursive_font_family": "", + "databases_disabled": False, + "default_encoding": "iso-8859-1", + "default_fixed_font_size": 0, + "default_font_size": 0, + "developer_tools_disabled": False, + "dom_paste_disabled": False, + "drag_drop_disabled": False, + "encoding_detector_enabled": False, + "fantasy_font_family": "", + "file_access_from_file_urls_allowed": False, + "fixed_font_family": "", + "fullscreen_enabled": False, + "history_disabled": False, + "hyperlink_auditing_disabled": False, + "image_load_disabled": False, + "java_disabled": False, + "javascript_access_clipboard_disallowed": False, + "javascript_close_windows_disallowed": False, + "javascript_disabled": False, + "javascript_open_windows_disallowed": False, + "load_drops_disabled": False, + "local_storage_disabled": False, + "minimum_font_size": 0, + "minimum_logical_font_size": 0, + "page_cache_disabled": False, + "plugins_disabled": False, + "remote_fonts_disabled": False, + "sans_serif_font_family": "", + "serif_font_family": "", + "shrink_standalone_images_to_fit": False, + "site_specific_quirks_disabled": False, + "standard_font_family": "", + "tab_to_links_disabled": False, + "text_area_resize_disabled": False, + "universal_access_from_file_urls_allowed": False, + "user_style_sheet_enabled": False, + "user_style_sheet_location": "", + "web_security_disabled": False, + "webgl_disabled": False, + "xss_auditor_enabled": False, +} + +# +# Browser object. +# + +class Browser: + + def CanGoBack(self): + return False + + def CanGoForward(self): + return False + + def ClearHistory(self): + return None + + def CloseBrowser(self): + return None + + def CloseDevTools(self): + return None + + def Find(self, searchID, searchText, forward, matchCase, findNext): + return None + + def GetClientCallback(self, name): + return callback + + def GetClientCallbacksDict(self): + return {} + + def GetFocusedFrame(self): + return Frame() + + def GetFrame(self): + return Frame() + + def GetFrameNames(self): + return ["", ""] + + def GetIdentifier(self): + return 0 + + def GetImage(self, paintElementType, width, height): + return PaintBuffer() + + def GetJavascriptBindings(self): + return JavascriptBindings() + + def GetMainFrame(self): + return Frame() + + def GetOpenerWindowHandle(self): + return 0 + + def GetOuterWindowHandle(self): + return 0 + + def GetSize(self, paintElementType): + return (0,0,) + + def GetUserData(self, key): + return None + + def GetWindowID(self): + return windowID + + def GetWindowHandle(self): + return 0 + + def GetZoomLevel(self): + return 0.0 + + def GoBack(self): + return None + + def GoForward(self): + return None + + def HasDocument(self): + return False + + def HidePopup(self): + return None + + def Invalidate(self, dirtyRect): + return None + + def IsFullscreen(self): + return False + + def IsPopup(self): + return False + + def IsPopupVisible(self): + return False + + def IsWindowRenderingDisabled(self): + return False + + def Reload(self): + return None + + def ReloadIgnoreCache(self): + return None + + def SendKeyEvent(self, keyType, keyInfo, modifiers): + return None + + def SendMouseClickEvent(self, x, y, mouseButtonType, mouseUp, clickCount): + return None + + def SendMouseMoveEvent(self, x, y, mouseLeave): + return None + + def SendMouseWheelEvent(self, x, y, deltaX, deltaY): + return None + + def SendFocusEvent(self, setFocus): + return None + + def SendCaptureLostEvent(self): + return None + + def SetClientCallback(self, name, callback): + return None + + def SetClientHandler(self, clientHandler): + return None + + def SetFocus(self, enable): + return None + + def SetJavascriptBindings(self, javascriptBindings): + return None + + def SetSize(self, paintElementType, width, height): + return None + + def SetZoomLevel(self, zoomLevel): + return None + + def SetUserData(self, key, value): + return None + + def ShowDevTools(self): + return None + + def StopLoad(self): + return None + + def StopFinding(self, clearSelection): + return None + + def ToggleFullscreen(self): + return None + +# +# Frame object. +# + +class Frame: + + def Copy(self): + return None + + def Cut(self): + return None + + def Delete(self): + return None + + def ExecuteJavascript(self, jsCode, scriptUrl=None, startLine=None): + return None + + def GetIdentifier(self): + return 0 + + def GetName(self): + return "" + + def GetProperty(self, name): + return mixed + + def GetSource(self): + return "" + + def GetText(self): + return "" + + def GetUrl(self): + return "" + + def IsFocused(self): + return False + + def IsMain(self): + return False + + def LoadString(self, value, url): + return None + + def LoadUrl(self, url): + return None + + def Paste(self): + return None + + def Print(self): + return None + + def Redo(self): + return None + + def SelectAll(self): + return None + + def SetProperty(self, name, value): + return None + + def Undo(self): + return None + + def ViewSource(self): + return None + +class Response: + + def GetStatus(self): + return 0 + + def SetStatus(self, status): + return None + + def GetStatusText(self): + return "" + + def SetStatusText(self, statusText): + return None + + def GetMimeType(self): + return "" + + def SetMimeType(self, mimeType): + return None + + def GetHeader(self, name): + return "" + + def GetHeaderMap(self): + return {} + + def GetHeaderMultimap(self): + return [("","")] + + def SetHeaderMap(self, headerMap={}): + return None + + def SetHeaderMultimap(self, headerMultimap=[]): + return None + +class PaintBuffer: + + def GetIntPointer(self): + return 0 + + def GetString(self, mode="bgra", origin="top-left"): + return "" + +class JavascriptBindings: + + def __init__(self, bindToFrames=False, bindToPopups=False): + return None + + def IsValueAllowed(self, value): + return False + + def Rebind(self): + return None + + def SetFunction(self, name, func): + return None + + def SetObject(self, name, obj): + return None + + def SetProperty(self, name, value): + return None + +class JavascriptCallback: + + def Call(self, param1, param2, param3_etc): + return mixed + + def GetName(self): + return name + +class WindowUtils: + + @staticmethod + def OnSetFocus(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnSize(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnEraseBackground(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def SetTitle(pyBrowser, pyTitle): + return None + + @staticmethod + def SetIcon(pyBrowser, icon="inherit"): + return None + +# +# DisplayHandler. +# + +# statusType constants (OnStatusMessage). +STATUSTYPE_TEXT = 0 +STATUSTYPE_MOUSEOVER_URL = 0 +STATUSTYPE_KEYBOARD_FOCUS_URL = 0 + +def DisplayHandler_OnAddressChange(browser, frame, url): + return None + +def DisplayHandler_OnConsoleMessage(browser, message, source, line): + return False + +def DisplayHandler_OnContentsSizeChange(browser, frame, width, height): + return None + +def DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward): + return None + +def DisplayHandler_OnStatusMessage(browser, text, statusType): + return None + +def DisplayHandler_OnTitleChange(browser, title): + return None + +def DisplayHandler_OnTooltip(browser, text_out=[""]): + return False + +# +# KeyboardHandler. +# + +def KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript): + return False + +# keyCode constants (OnKeyEvent). +VK_0=0x30 +VK_1=0x31 +VK_2=0x32 +VK_3=0x33 +VK_4=0x34 +VK_5=0x35 +VK_6=0x36 +VK_7=0x37 +VK_8=0x38 +VK_9=0x39 +VK_A=0x041 +VK_B=0x042 +VK_C=0x043 +VK_D=0x044 +VK_E=0x045 +VK_F=0x046 +VK_G=0x047 +VK_H=0x048 +VK_I=0x049 +VK_J=0x04A +VK_K=0x04B +VK_L=0x04C +VK_M=0x04D +VK_N=0x04E +VK_O=0x04F +VK_P=0x050 +VK_Q=0x051 +VK_R=0x052 +VK_S=0x053 +VK_T=0x054 +VK_U=0x055 +VK_V=0x056 +VK_W=0x057 +VK_X=0x058 +VK_Y=0x059 +VK_Z=0x05A +VK_F1=0x70 +VK_F2=0x71 +VK_F3=0x72 +VK_F4=0x73 +VK_F5=0x74 +VK_F6=0x75 +VK_F7=0x76 +VK_F8=0x77 +VK_F9=0x78 +VK_F10=0x79 +VK_F11=0x7A +VK_F12=0x7B +VK_F13=0x7C +VK_F14=0x7D +VK_F15=0x7E +VK_F16=0x7F +VK_F17=0x80 +VK_F18=0x81 +VK_F19=0x82 +VK_F20=0x83 +VK_F21=0x84 +VK_F22=0x85 +VK_F23=0x86 +VK_F24=0x87 +VK_LSHIFT=0xA0 +VK_RSHIFT=0xA1 +VK_LCONTROL=0xA2 +VK_RCONTROL=0xA3 +VK_LMENU=0xA4 +VK_RMENU=0xA5 +VK_BACK=0x08 +VK_TAB=0x09 +VK_SPACE=0x20 +VK_PRIOR=0x21 +VK_NEXT=0x22 +VK_END=0x23 +VK_HOME=0x24 +VK_LEFT=0x25 +VK_UP=0x26 +VK_RIGHT=0x27 +VK_DOWN=0x28 +VK_SELECT=0x29 +VK_PRINT=0x2A +VK_EXECUTE=0x2B +VK_SNAPSHOT=0x2C +VK_INSERT=0x2D +VK_DELETE=0x2E +VK_HELP=0x2F +VK_SHIFT=0x10 +VK_CONTROL=0x11 +VK_MENU=0x12 +VK_PAUSE=0x13 +VK_CAPITAL=0x14 +VK_CLEAR=0x0C +VK_RETURN=0x0D +VK_ESCAPE=0x1B +VK_LWIN=0x5B +VK_RWIN=0x5C +VK_APPS=0x5D +VK_SLEEP=0x5F +VK_NUMPAD0=0x60 +VK_NUMPAD1=0x61 +VK_NUMPAD2=0x62 +VK_NUMPAD3=0x63 +VK_NUMPAD4=0x64 +VK_NUMPAD5=0x65 +VK_NUMPAD6=0x66 +VK_NUMPAD7=0x67 +VK_NUMPAD8=0x68 +VK_NUMPAD9=0x69 +VK_BROWSER_BACK=0xA6 +VK_BROWSER_FORWARD=0xA7 +VK_BROWSER_REFRESH=0xA8 +VK_BROWSER_STOP=0xA9 +VK_BROWSER_SEARCH=0xAA +VK_BROWSER_FAVORITES=0xAB +VK_BROWSER_HOME=0xAC +VK_VOLUME_MUTE=0xAD +VK_VOLUME_DOWN=0xAE +VK_VOLUME_UP=0xAF +VK_MEDIA_NEXT_TRACK=0xB0 +VK_MEDIA_PREV_TRACK=0xB1 +VK_MEDIA_STOP=0xB2 +VK_MEDIA_PLAY_PAUSE=0xB3 +VK_LAUNCH_MAIL=0xB4 +VK_LAUNCH_MEDIA_SELECT=0xB5 +VK_LAUNCH_APP1=0xB6 +VK_LAUNCH_APP2=0xB7 +VK_MULTIPLY=0x6A +VK_ADD=0x6B +VK_SEPARATOR=0x6C +VK_SUBTRACT=0x6D +VK_DECIMAL=0x6E +VK_DIVIDE=0x6F +VK_NUMLOCK=0x90 +VK_SCROLL=0x91 +VK_LBUTTON=0x01 +VK_RBUTTON=0x02 +VK_CANCEL=0x03 +VK_MBUTTON=0x04 +VK_XBUTTON1=0x05 +VK_XBUTTON2=0x06 +VK_KANA=0x15 +VK_HANGEUL=0x15 +VK_HANGUL=0x15 +VK_JUNJA=0x17 +VK_FINAL=0x18 +VK_HANJA=0x19 +VK_KANJI=0x19 +VK_CONVERT=0x1C +VK_NONCONVERT=0x1D +VK_ACCEPT=0x1E +VK_MODECHANGE=0x1F +VK_PROCESSKEY=0xE5 +VK_PACKET=0xE7 +VK_ICO_HELP=0xE3 +VK_ICO_00=0xE4 +VK_ICO_CLEAR=0xE6 + +# eventType constants (OnKeyEvent). +KEYEVENT_RAWKEYDOWN = 0 +KEYEVENT_KEYDOWN = 0 +KEYEVENT_KEYUP = 0 +KEYEVENT_CHAR = 0 + +# Constants for checking modifiers param (OnKeyEvent), for use with IsKeyModifier() function. +KEY_NONE = 0 +KEY_SHIFT = 0 +KEY_CTRL = 0 +KEY_ALT = 0 +KEY_META = 0 +KEY_KEYPAD = 0 + +# +# LoadHandler. +# + +def LoadHandler_OnLoadEnd(browser, frame, httpStatusCode): + return None + +def LoadHandler_OnLoadError(browser, frame, errorCode, failedUrl, errorText_out=[""]): + return False + +def LoadHandler_OnLoadStart(browser, frame): + return None + +# errorCode constants (OnLoadError). +ERR_FAILED = 0 +ERR_ABORTED = 0 +ERR_INVALID_ARGUMENT = 0 +ERR_INVALID_HANDLE = 0 +ERR_FILE_NOT_FOUND = 0 +ERR_TIMED_OUT = 0 +ERR_FILE_TOO_BIG = 0 +ERR_UNEXPECTED = 0 +ERR_ACCESS_DENIED = 0 +ERR_NOT_IMPLEMENTED = 0 +ERR_CONNECTION_CLOSED = 0 +ERR_CONNECTION_RESET = 0 +ERR_CONNECTION_REFUSED = 0 +ERR_CONNECTION_ABORTED = 0 +ERR_CONNECTION_FAILED = 0 +ERR_NAME_NOT_RESOLVED = 0 +ERR_INTERNET_DISCONNECTED = 0 +ERR_SSL_PROTOCOL_ERROR = 0 +ERR_ADDRESS_INVALID = 0 +ERR_ADDRESS_UNREACHABLE = 0 +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = 0 +ERR_TUNNEL_CONNECTION_FAILED = 0 +ERR_NO_SSL_VERSIONS_ENABLED = 0 +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = 0 +ERR_SSL_RENEGOTIATION_REQUESTED = 0 +ERR_CERT_COMMON_NAME_INVALID = 0 +ERR_CERT_DATE_INVALID = 0 +ERR_CERT_AUTHORITY_INVALID = 0 +ERR_CERT_CONTAINS_ERRORS = 0 +ERR_CERT_NO_REVOCATION_MECHANISM = 0 +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 0 +ERR_CERT_REVOKED = 0 +ERR_CERT_INVALID = 0 +ERR_CERT_END = 0 +ERR_INVALID_URL = 0 +ERR_DISALLOWED_URL_SCHEME = 0 +ERR_UNKNOWN_URL_SCHEME = 0 +ERR_TOO_MANY_REDIRECTS = 0 +ERR_UNSAFE_REDIRECT = 0 +ERR_UNSAFE_PORT = 0 +ERR_INVALID_RESPONSE = 0 +ERR_INVALID_CHUNKED_ENCODING = 0 +ERR_METHOD_NOT_SUPPORTED = 0 +ERR_UNEXPECTED_PROXY_AUTH = 0 +ERR_EMPTY_RESPONSE = 0 +ERR_RESPONSE_HEADERS_TOO_BIG = 0 +ERR_CACHE_MISS = 0 +ERR_INSECURE_RESPONSE = 0 + +# +# RequestHandler. +# + +def RequestHandler_OnResourceRedirect(browser, oldUrl, newUrl_out=[""]): + return None + +def RequestHandler_OnResourceResponse(browser, url, response, filter_out=[None]): + return None + +def RequestHandler_OnProtocolExecution(browser, url, allowOSExecution_out=[False]): + return False + +def RequestHandler_GetAuthCredentials(browser, isProxy, host, port, realm, scheme, username_out=[""], password_out=[""]): + return False + +# navType constants (OnBeforeBrowse). +NAVTYPE_LINKCLICKED = 0 +NAVTYPE_FORMSUBMITTED = 0 +NAVTYPE_BACKFORWARD = 0 +NAVTYPE_RELOAD = 0 +NAVTYPE_FORMRESUBMITTED = 0 +NAVTYPE_OTHER = 0 +NAVTYPE_LINKDROPPED = 0 + +# +# JavascriptContextHandler +# + +def JavascriptContextHandler_OnUncaughtException(browser, frame, exception, stackTrace): + return None + +# +# LifespanHandler +# + +def LifespanHandler_DoClose(browser): + return False + +def LifespanHandler_OnAfterCreated(browser): + return None + +def LifespanHandler_OnBeforeClose(browser): + return None + +def LifespanHandler_RunModal(browser): + return False + +# +# RenderHandler +# + +PET_VIEW = 0 +PET_POPUP = 0 + +KEYTYPE_KEYUP = 0 +KEYTYPE_KEYDOWN = 0 +KEYTYPE_CHAR = 0 + +MOUSEBUTTON_LEFT = 0 +MOUSEBUTTON_MIDDLE = 0 +MOUSEBUTTON_RIGHT = 0 + +def RenderHandler_GetViewRect(browser, out_rect): + return False + +def RenderHandler_GetScreenRect(browser, out_rect): + return False + +def RenderHandler_GetScreenPoint(browser, viewX, viewY, out_screenCoordinates): + return False + +def RenderHandler_OnPopupShow(browser, show): + return None + +def RenderHandler_OnPopupSize(browser, rect): + return None + +def RenderHandler_OnPaint(browser, paintElementType, out_dirtyRects, + paintBuffer): + return None + +def RenderHandler_OnCursorChange(browser, cursor): + return None diff --git a/cefpython/cef1/linux/binaries_32bit/cefsimple.html b/cefpython/cef1/linux/binaries_32bit/cefsimple.html new file mode 100644 index 00000000..f46f773c --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/cefsimple.html @@ -0,0 +1,37 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Welcome to CEF Python - bindings for the Chromium Embedded Framework.

+ +Project's website: http://code.google.com/p/cefpython/
+Wiki documentation: http://code.google.com/p/cefpython/wiki/
+Support forum: https://groups.google.com/group/cefpython?hl=en
+ +

Google Search

+ +http://www.google.com/ + +

User agent

+ + + +

Popup

+ + + window.open('cefsimple.html') + +










+










+










+ + + diff --git a/cefpython/cef1/linux/binaries_32bit/chrome.pak b/cefpython/cef1/linux/binaries_32bit/chrome.pak new file mode 100644 index 00000000..567a768a Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/chrome.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/devtools_resources.pak b/cefpython/cef1/linux/binaries_32bit/devtools_resources.pak new file mode 100644 index 00000000..00ed699b Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/devtools_resources.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/libcef.so b/cefpython/cef1/linux/binaries_32bit/libcef.so new file mode 100755 index 00000000..10a09484 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/libcef.so differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/am.pak b/cefpython/cef1/linux/binaries_32bit/locales/am.pak new file mode 100644 index 00000000..3749afe0 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/am.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ar.pak b/cefpython/cef1/linux/binaries_32bit/locales/ar.pak new file mode 100644 index 00000000..ea7f660e Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ar.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/bg.pak b/cefpython/cef1/linux/binaries_32bit/locales/bg.pak new file mode 100644 index 00000000..29c4cc32 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/bg.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/bn.pak b/cefpython/cef1/linux/binaries_32bit/locales/bn.pak new file mode 100644 index 00000000..6658c44e Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/bn.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ca.pak b/cefpython/cef1/linux/binaries_32bit/locales/ca.pak new file mode 100644 index 00000000..b5591db8 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ca.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/cs.pak b/cefpython/cef1/linux/binaries_32bit/locales/cs.pak new file mode 100644 index 00000000..47b46641 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/cs.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/da.pak b/cefpython/cef1/linux/binaries_32bit/locales/da.pak new file mode 100644 index 00000000..92752174 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/da.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/de.pak b/cefpython/cef1/linux/binaries_32bit/locales/de.pak new file mode 100644 index 00000000..9ea672bb Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/de.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/el.pak b/cefpython/cef1/linux/binaries_32bit/locales/el.pak new file mode 100644 index 00000000..addb3984 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/el.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/en-GB.pak b/cefpython/cef1/linux/binaries_32bit/locales/en-GB.pak new file mode 100644 index 00000000..239dc460 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/en-GB.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/en-US.pak b/cefpython/cef1/linux/binaries_32bit/locales/en-US.pak new file mode 100644 index 00000000..6acdf9dd Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/en-US.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/es-419.pak b/cefpython/cef1/linux/binaries_32bit/locales/es-419.pak new file mode 100644 index 00000000..889e5a9b Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/es-419.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/es.pak b/cefpython/cef1/linux/binaries_32bit/locales/es.pak new file mode 100644 index 00000000..d771963e Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/es.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/et.pak b/cefpython/cef1/linux/binaries_32bit/locales/et.pak new file mode 100644 index 00000000..0775bd23 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/et.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/fa.pak b/cefpython/cef1/linux/binaries_32bit/locales/fa.pak new file mode 100644 index 00000000..7d8c8578 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/fa.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/fi.pak b/cefpython/cef1/linux/binaries_32bit/locales/fi.pak new file mode 100644 index 00000000..7edb1bf9 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/fi.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/fil.pak b/cefpython/cef1/linux/binaries_32bit/locales/fil.pak new file mode 100644 index 00000000..ab55920c Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/fil.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/fr.pak b/cefpython/cef1/linux/binaries_32bit/locales/fr.pak new file mode 100644 index 00000000..ea53e029 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/fr.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/gu.pak b/cefpython/cef1/linux/binaries_32bit/locales/gu.pak new file mode 100644 index 00000000..9e984316 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/gu.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/he.pak b/cefpython/cef1/linux/binaries_32bit/locales/he.pak new file mode 100644 index 00000000..e9f407e5 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/he.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/hi.pak b/cefpython/cef1/linux/binaries_32bit/locales/hi.pak new file mode 100644 index 00000000..45d08355 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/hi.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/hr.pak b/cefpython/cef1/linux/binaries_32bit/locales/hr.pak new file mode 100644 index 00000000..e20580e6 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/hr.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/hu.pak b/cefpython/cef1/linux/binaries_32bit/locales/hu.pak new file mode 100644 index 00000000..7d2c2f24 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/hu.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/id.pak b/cefpython/cef1/linux/binaries_32bit/locales/id.pak new file mode 100644 index 00000000..6d9e4510 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/id.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/it.pak b/cefpython/cef1/linux/binaries_32bit/locales/it.pak new file mode 100644 index 00000000..0d10cb60 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/it.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ja.pak b/cefpython/cef1/linux/binaries_32bit/locales/ja.pak new file mode 100644 index 00000000..b29e7daa Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ja.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/kn.pak b/cefpython/cef1/linux/binaries_32bit/locales/kn.pak new file mode 100644 index 00000000..316496f0 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/kn.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ko.pak b/cefpython/cef1/linux/binaries_32bit/locales/ko.pak new file mode 100644 index 00000000..86b0841d Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ko.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/lt.pak b/cefpython/cef1/linux/binaries_32bit/locales/lt.pak new file mode 100644 index 00000000..be6444f2 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/lt.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/lv.pak b/cefpython/cef1/linux/binaries_32bit/locales/lv.pak new file mode 100644 index 00000000..ca37399c Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/lv.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ml.pak b/cefpython/cef1/linux/binaries_32bit/locales/ml.pak new file mode 100644 index 00000000..25782a80 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ml.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/mr.pak b/cefpython/cef1/linux/binaries_32bit/locales/mr.pak new file mode 100644 index 00000000..253c6633 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/mr.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ms.pak b/cefpython/cef1/linux/binaries_32bit/locales/ms.pak new file mode 100644 index 00000000..3bfcea5c Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ms.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/nb.pak b/cefpython/cef1/linux/binaries_32bit/locales/nb.pak new file mode 100644 index 00000000..1868484f Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/nb.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/nl.pak b/cefpython/cef1/linux/binaries_32bit/locales/nl.pak new file mode 100644 index 00000000..92303e44 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/nl.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/pl.pak b/cefpython/cef1/linux/binaries_32bit/locales/pl.pak new file mode 100644 index 00000000..af8e3100 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/pl.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/pt-BR.pak b/cefpython/cef1/linux/binaries_32bit/locales/pt-BR.pak new file mode 100644 index 00000000..9bfea0b4 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/pt-BR.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/pt-PT.pak b/cefpython/cef1/linux/binaries_32bit/locales/pt-PT.pak new file mode 100644 index 00000000..e0b2a9fb Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/pt-PT.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ro.pak b/cefpython/cef1/linux/binaries_32bit/locales/ro.pak new file mode 100644 index 00000000..213b3f47 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ro.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ru.pak b/cefpython/cef1/linux/binaries_32bit/locales/ru.pak new file mode 100644 index 00000000..b2fd1200 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ru.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/sk.pak b/cefpython/cef1/linux/binaries_32bit/locales/sk.pak new file mode 100644 index 00000000..127c0a07 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/sk.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/sl.pak b/cefpython/cef1/linux/binaries_32bit/locales/sl.pak new file mode 100644 index 00000000..d5ab0933 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/sl.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/sr.pak b/cefpython/cef1/linux/binaries_32bit/locales/sr.pak new file mode 100644 index 00000000..e9853962 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/sr.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/sv.pak b/cefpython/cef1/linux/binaries_32bit/locales/sv.pak new file mode 100644 index 00000000..37a6eca3 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/sv.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/sw.pak b/cefpython/cef1/linux/binaries_32bit/locales/sw.pak new file mode 100644 index 00000000..13c0c0f2 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/sw.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/ta.pak b/cefpython/cef1/linux/binaries_32bit/locales/ta.pak new file mode 100644 index 00000000..322af150 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/ta.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/te.pak b/cefpython/cef1/linux/binaries_32bit/locales/te.pak new file mode 100644 index 00000000..c67cf997 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/te.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/th.pak b/cefpython/cef1/linux/binaries_32bit/locales/th.pak new file mode 100644 index 00000000..7813f91c Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/th.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/tr.pak b/cefpython/cef1/linux/binaries_32bit/locales/tr.pak new file mode 100644 index 00000000..1867524d Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/tr.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/uk.pak b/cefpython/cef1/linux/binaries_32bit/locales/uk.pak new file mode 100644 index 00000000..c0c5c758 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/uk.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/vi.pak b/cefpython/cef1/linux/binaries_32bit/locales/vi.pak new file mode 100644 index 00000000..ec74997e Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/vi.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/zh-CN.pak b/cefpython/cef1/linux/binaries_32bit/locales/zh-CN.pak new file mode 100644 index 00000000..d82fd560 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/zh-CN.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/locales/zh-TW.pak b/cefpython/cef1/linux/binaries_32bit/locales/zh-TW.pak new file mode 100644 index 00000000..10aa9001 Binary files /dev/null and b/cefpython/cef1/linux/binaries_32bit/locales/zh-TW.pak differ diff --git a/cefpython/cef1/linux/binaries_32bit/pygtk_.py b/cefpython/cef1/linux/binaries_32bit/pygtk_.py new file mode 100644 index 00000000..77141a51 --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/pygtk_.py @@ -0,0 +1,191 @@ +# An example of embedding CEF browser in PyGTK on Linux. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython1 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import re + +def GetApplicationPath(file=None): + import re, os, platform + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + vbox = None + + def __init__(self): + + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=600, height=400) + self.mainWindow.set_title('PyGTK CEF example') + self.mainWindow.realize() + + self.vbox = gtk.VBox(False, 0) + self.vbox.pack_start(self.CreateMenu(), False, False, 0) + self.mainWindow.add(self.vbox) + + m = re.search("GtkVBox at 0x(\w+)", str(self.vbox)) + hexID = m.group(1) + windowID = int(hexID, 16) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # Flash will crash app in CEF 1 on Linux, setting + # plugins_disabled to True. + browserSettings={"plugins_disabled": True}, + navigateUrl="file://"+GetApplicationPath("cefsimple.html")) + + # Must be show_all() for VBox otherwise browser doesn't + # appear when you just call show(). + self.vbox.show() + + self.mainWindow.show() + gobject.timeout_add(10, self.OnTimer) + + def CreateMenu(self): + + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + + about = gtk.MenuItem('About') + about.show() + aboutmenu = gtk.Menu() + item = gtk.MenuItem('CEF Python') + aboutmenu.append(item) + item.show() + about.set_submenu(aboutmenu) + + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + + return menubar + + def OnWidgetClick(self, widget, data): + + self.mainWindow.get_window().focus() + + def OnTimer(self): + + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + + # This function is currently not called by any of code, + # but if you would like for browser to have automatic focus + # add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + self.browser.SetFocus(True) + + def OnExit(self, widget, data=None): + + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + + version = '.'.join(map(str, list(gtk.gtk_version))) + print('GTK version: %s' % version) + + sys.excepthook = ExceptHook + cefpython.g_debug = True + cefpython.g_debugFile = GetApplicationPath("debug.log") + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory() + } + cefpython.Initialize(settings) + + gobject.threads_init() # timer for messageloop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef1/linux/binaries_32bit/wxpython.html b/cefpython/cef1/linux/binaries_32bit/wxpython.html new file mode 100644 index 00000000..ff674443 --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/wxpython.html @@ -0,0 +1,172 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Use mouse context menu to go Back/Forward in history navigation. + + + +

Google Search

+http://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('wxpython.html') + + + + +

RequestHandler tests

+ +

See messages in the console.

+ +OnBeforeBrowse() - navigate to see message: +wxpython.html +

+ +OnBeforeBrowse() / OnBeforeResourceLoad() - test request.GetPostData() +and request.SetPostData(): +submit a form: + + https://accounts.google.com/ServiceLogin, +upload a file: + + http://encodable.com/uploaddemo/ +

+ +OnBeforeResourceLoad() - try loading nonexistent css file locally: + + LoadCssFile('nonexistent.css') + +

+ +OnBeforeResourceLoad() - try replacing a resource on the fly: + + LoadCssFile('replace-on-the-fly.css') +(css content: body { color: red; }) +

+ +OnResourceRedirect() - try loading this url: + + http://tinyurl.com/google404redirect +

+ +OnResourceResponse() - try loading nonexistent css file via http: + + LoadCssFile('http://www.google.com/404.css') +

+ +OnResourceResponse() - try filtering content of the resource: + + LoadCssFile('content-filter/replace-on-the-fly.css') +(new css content: body { color: green; } and body h3 { color: orange; } ) +

+ + + + + +

WebRequest test

+ +See the console for messages.
+ + + external.WebRequest('https://code.google.com/robots.txt') + +

Frame.CallFunction() test

+ + + + external.DoCallFunction() + + + + +

Cookie tests

+ +See messages in the console. +

+ +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. Visit + + http://www.html-kit.com/tools/cookietester/ and set some cookie, +then go back to this page using the context menu and open a + + new popup window, the cookie should not appear in the popup browser window. +

+ +CookieManager.VisitAllCookies() - visit all cookies: +external.VisitAllCookies() +(note: visit some http:// webpage first, otherwise cookie manager is not +yet created) +

+ +CookieManager.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +- visit a subset of cookies given the url, test: +external.VisitUrlCookies() +

+ +CookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + {name:"Created_Via_Python", value:"yeah really"}) - create the cookie: + external.SetCookie() +

+ +CookieManager.DeleteCookies() - delete the single cookie previously created +via SetCookie(): + external.DeleteCookies() +

+ + + + +

DragHandler test

+ +Try dragging a file, or a text/html fragment to the browser window +and look for the messages in the console. In the wxpython.py script see +ClientHandler.OnDragStart() and OnDragEnter(). + + + + +

DownloadHandler test

+ +Try downloading this file (838 KiB):
+ + http://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip +
+See messages in the console. +The file will be saved in the ./downloads/ directory. + + + + + + diff --git a/cefpython/cef1/linux/binaries_32bit/wxpython.py b/cefpython/cef1/linux/binaries_32bit/wxpython.py new file mode 100644 index 00000000..9571f9c6 --- /dev/null +++ b/cefpython/cef1/linux/binaries_32bit/wxpython.py @@ -0,0 +1,528 @@ +# An example of embedding CEF browser in wxPython on Linux. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython1 import cefpython + +import wx +import time +import re +import uuid + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + initialized = False + idleCount = 0 + box = None + + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython example', size=(800,600)) + self.CreateMenu() + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # Flash will crash app in CEF 1 on Linux, setting + # plugins_disabled to True. + browserSettings={"plugins_disabled": True}, + navigateUrl="file://"+GetApplicationPath("wxpython.html")) + + self.browser.SetClientHandler(ClientHandler()) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=False) + jsBindings.SetObject("external", JavascriptBindings(self.browser)) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + self.browser.CloseBrowser() + self.Destroy() + + def OnIdle(self, event): + # self.idleCount += 1 + # print("wxpython.py: OnIdle() %d" % self.idleCount) + cefpython.MessageLoopWork() + +class JavascriptBindings: + mainBrowser = None + webRequest = None + webRequestId = 0 + cookieVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def WebRequest(self, url): + request = cefpython.Request.CreateRequest() + request.SetUrl(url) + webRequestClient = WebRequestClient() + # Must keep the reference otherwise WebRequestClient + # callbacks won't be called. + self.webRequest = cefpython.WebRequest.CreateWebRequest(request, + webRequestClient) + + def DoCallFunction(self): + self.mainBrowser.GetMainFrame().CallFunction( + "MyFunction", "abc", 12, [1,2,3], {"qwe": 456, "rty": 789}) + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\nCookie created! Visit html-kit cookietester to see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\nCookie deleted! Visit html-kit cookietester to see the result") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\nCookieVisitor.Visit(): total cookies: %s" % total) + print("\nCookieVisitor.Visit(): cookie:") + print(cookie.Get()) + # True to continue visiting cookies + return True + +class WebRequestClient: + def OnStateChange(self, webRequest, state): + stateName = "unknown" + for key, value in cefpython.WebRequest.State.iteritems(): + if value == state: + stateName = key + print("\nWebRequestClient::OnStateChange(): state = %s" % stateName) + + def OnRedirect(self, webRequest, request, response): + print("\nWebRequestClient::OnRedirect(): url = %s" % ( + request.GetUrl()[:80])) + + def OnHeadersReceived(self, webRequest, response): + print("\nWebRequestClient::OnHeadersReceived(): headers = %s" % ( + response.GetHeaderMap())) + + def OnProgress(self, webRequest, bytesSent, totalBytesToBeSent): + print("\nWebRequestClient::OnProgress(): bytesSent = %s, " + "totalBytesToBeSent = %s" % (bytesSent, totalBytesToBeSent)) + + def OnData(self, webRequest, data): + print("\nWebRequestClient::OnData(): data:") + print("-" * 60) + print(data) + print("-" * 60) + + def OnError(self, webRequest, errorCode): + print("\nWebRequestClient::OnError(): errorCode = %s" % errorCode) + +class ContentFilterHandler: + def OnData(self, data, substitute_data): + if data == "body { color: red; }": + substitute_data.SetData("body { color: green; }") + + def OnDrain(self, remainder): + remainder.SetData("body h3 { color: orange; }") + +class ClientHandler: + + # -------------------------------------------------------------------------- + # RequestHandler + # -------------------------------------------------------------------------- + + contentFilter = None + + def OnBeforeBrowse(self, browser, frame, request, navType, isRedirect): + # - frame.GetUrl() returns current url + # - request.GetUrl() returns new url + # - Return true to cancel the navigation or false to allow + # the navigation to proceed. + # - Modifying headers or post data can be done only in + # OnBeforeResourceLoad() + print("\nOnBeforeBrowse(): request.GetUrl() = %s, " + "request.GetHeaderMap(): %s" % ( + request.GetUrl()[:80], request.GetHeaderMap())) + if request.GetMethod() == "POST": + print("\nOnBeforeBrowse(): POST data: %s" % ( + request.GetPostData())) + + def OnBeforeResourceLoad(self, browser, request, redirectUrl, + streamReader, response, loadFlags): + print("\nOnBeforeResourceLoad(): request.GetUrl() = %s" % ( + request.GetUrl()[:80])) + if request.GetMethod() == "POST": + if request.GetUrl().startswith( + "https://accounts.google.com/ServiceLogin"): + postData = request.GetPostData() + postData["Email"] = "--changed via python" + request.SetPostData(postData) + print("\nOnBeforeResourceLoad(): modified POST data: %s" % ( + request.GetPostData())) + if request.GetUrl().endswith("replace-on-the-fly.css"): + print("\nOnBeforeResourceLoad(): replacing css on the fly") + response.SetStatus(200) + response.SetStatusText("OK") + response.SetMimeType("text/css") + streamReader.SetData("body { color: red; }") + + def OnResourceRedirect(self, browser, oldUrl, newUrl): + print("\nOnResourceRedirect(): oldUrl: %s, newUrl: %s" % ( + oldUrl, newUrl[0])) + + def OnResourceResponse(self, browser, url, response, contentFilter): + print("\nOnResourceResponse(): url = %s, headers = %s" % ( + url[:80], response.GetHeaderMap())) + if url.endswith("content-filter/replace-on-the-fly.css"): + print("\nOnResourceResponse(): setting contentFilter handler") + contentFilter.SetHandler(ContentFilterHandler()) + # Must keep the reference to contentFilter otherwise + # ContentFilterHandler callbacks won't be called. + self.contentFilter = contentFilter + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + cookieManager = cefpython.CookieManager.CreateManager("") + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + # -------------------------------------------------------------------------- + # DragHandler + # -------------------------------------------------------------------------- + + def OnDragStart(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragStart(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + return False + + def OnDragEnter(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragEnter(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + return False + + # -------------------------------------------------------------------------- + # DownloadHandler + # -------------------------------------------------------------------------- + + downloadHandler = None + + def GetDownloadHandler(self, browser, mimeType, filename, contentLength): + # Close the browser window if it is a popup with + # no other document contents. + if browser.IsPopup() and not browser.HasDocument(): + browser.CloseBrowser() + # The reference to DownloadHandler must be kept alive + # while download proceeds. + if self.downloadHandler and self.downloadHandler.downloading: + print("\nDownload is already in progress") + return False + self.downloadHandler = DownloadHandler(mimeType, filename, + contentLength) + return self.downloadHandler + +class DownloadHandler: + mimeType = "" + filename = "" + contentLength = -1 # -1 means that file size was not provided. + fp = None + downloadsDir = "./downloads" + alreadyDownloaded = 0 + downloading = False + + def __init__(self, mimeType, filename, contentLength): + self.downloading = True + if not os.path.exists(self.downloadsDir): + os.mkdir(self.downloadsDir) + filename = filename.strip() + if not len(filename): + filename = self.GetUniqueFilename() + filename = self.GetSafeFilename(filename) + print("\nDownloadHandler() created") + print("mimeType: %s" % mimeType) + print("filename: %s" % filename) + print("contentLength: %s" % contentLength) + # Append ".downloading" to the filename, in OnComplete() + # when download finishes get rid of this extension. + filename += ".downloading" + if os.path.exists(self.downloadsDir+"/"+filename): + # If the last download did not succeed, the + # "xxx.downloading" might still be there. + os.remove(self.downloadsDir+"/"+filename) + self.mimeType = mimeType + self.filename = filename + self.contentLength = contentLength + self.fp = open(self.downloadsDir+"/"+filename, "wb") + + def GetSafeFilename(self, filename): + # TODO: + # - remove any unsafe characters (".." or "/" or "\" and + # others), the safest way is to have a regexp with a list + # safe characters. The dots ".." is a special case that + # needs to be treated separately. + if os.path.exists(self.downloadsDir+"/"+filename): + filename = self.GetUniqueFilename()[:4]+"_"+filename + assert not os.path.exists(self.downloadsDir+"/"+filename), ( + "File aready exists") + return filename + + def GetUniqueFilename(self): + # The filename may be empty, in that case generate + # an unique name. + # TODO: + # - guess the extension using the mimeType (but mimeType + # may also be empty), "text/css" => ".css". + return str(uuid.uuid4()).replace("-", "")[:16] + + def OnData(self, data): + # TODO: display progress in percentage or/and KiB/MiB. + if self.alreadyDownloaded == 0: + sys.stdout.write("Download progress: ") + sys.stdout.write(".") + sys.stdout.flush() + self.alreadyDownloaded += len(data) + self.fp.write(data) + # time.sleep(1) # Let's make the progress a bit slower (if cached) + # Return True to continue receiving data, False to cancel. + return True + + def OnComplete(self): + sys.stdout.write("\n") + sys.stdout.flush() + self.fp.close() + currentFile = self.downloadsDir+"/"+self.filename + newFilename = re.sub(".downloading$", "", self.filename) + os.rename(self.downloadsDir+"/"+self.filename, + self.downloadsDir+"/"+newFilename) + self.downloading = False + print("\nDownload complete!") + print("Total downloaded: %s" % self.PrettyBytes( + self.alreadyDownloaded)) + print("See the 'downloads' directory.") + + def PrettyBytes(self, bytes): + KiB = 1024 + return "%.3g KiB" % (bytes / KiB) + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("wxpython.py: OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +if __name__ == '__main__': + sys.excepthook = ExceptHook + cefpython.g_debug = True + cefpython.g_debugFile = GetApplicationPath("debug.log") + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory() + } + cefpython.Initialize(settings) + + print('wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + + cefpython.Shutdown() diff --git a/cefpython/cef1/linux/binaries_64bit/LICENSE.txt b/cefpython/cef1/linux/binaries_64bit/LICENSE.txt new file mode 100644 index 00000000..97f1e961 --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/LICENSE.txt @@ -0,0 +1,36 @@ +Copyright (c) 2012-2013 Czarek Tomczak. Portions Copyright +(c) 2008-2013 Marshall A.Greenblatt, 2006-2009 Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef1/linux/binaries_64bit/cefclient b/cefpython/cef1/linux/binaries_64bit/cefclient new file mode 100755 index 00000000..073cbb33 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/cefclient differ diff --git a/cefpython/cef1/linux/binaries_64bit/cefpython_py27.py b/cefpython/cef1/linux/binaries_64bit/cefpython_py27.py new file mode 100644 index 00000000..0b0e988c --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/cefpython_py27.py @@ -0,0 +1,815 @@ +# This file contains API for the "cefpython.pyd" module, all functions are dummy. +# Use it as a quick reference. Use it for code completion in your IDE. +# This file does NOT need to be distribitued along with binaries. + +raise Exception("A dummy API file was imported instead of the PYD module.") + +""" +Detailed documentation with examples can be found on wiki pages: +http://code.google.com/p/cefpython/w/list +""" + +# Global functions in cefpython module. + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl): + return Browser() + +def FormatJavascriptStackTrace(stackTrace): + return "" + +def GetBrowserByWindowHandle(windowHandle): + return Browser() + +def GetJavascriptStackTrace(frameLimit=100): + return [] + +def Initialize(applicationSettings={}): + return None + +def IsKeyModifier(key, modifiers): + return False + +def MessageLoop(): + return None + +def MessageLoopWork(): + return None + +def QuitMessageLoop(): + return None + +def Shutdown(): + return None + +def GetModuleDirectory(): + return "" + +# +# Settings +# + +# Values are dummy, these are NOT the defaults. +ApplicationSettings = { + "auto_detect_proxy_settings_enabled": False, + "cache_path": "", + "extra_plugin_paths": [""], + "graphics_implementation": ANGLE_IN_PROCESS, + "javascript_flags": "", + "local_storage_quota": 5*1024*1024, + "locale": "", + "locales_dir_path": "", + "log_file": "", + "log_severity": LOGSEVERITY_INFO, + "release_dcheck_enabled": False, + "multi_threaded_message_loop": False, + "pack_loading_disabled": False, + "product_version": "", + "resources_dir_path": "", + "session_storage_quota": 5*1024*1024, + "string_encoding": "utf-8", + "uncaught_exception_stack_size": 0, + "user_agent": "", +} + +# ApplicationSettings["log_severity"] +LOGSEVERITY_VERBOSE = 0 +LOGSEVERITY_INFO = 0 +LOGSEVERITY_WARNING = 0 +LOGSEVERITY_ERROR = 0 +LOGSEVERITY_ERROR_REPORT = 0 +LOGSEVERITY_DISABLE = 0 + +# ApplicationSettings["graphics_implementation"] +ANGLE_IN_PROCESS = 0 +ANGLE_IN_PROCESS_COMMAND_BUFFER = 0 +DESKTOP_IN_PROCESS = 0 +DESKTOP_IN_PROCESS_COMMAND_BUFFER = 0 + +# Values are dummy, these are NOT the defaults. +BrowserSettings = { + "accelerated_2d_canvas_disabled": False, + "accelerated_compositing_enabled": False, + "accelerated_filters_disabled": False, + "accelerated_layers_disabled": False, + "accelerated_plugins_disabled": False, + "accelerated_video_disabled": False, + "animation_frame_rate": 0, + "application_cache_disabled": False, + "author_and_user_styles_disabled": False, + "caret_browsing_enabled": False, + "cursive_font_family": "", + "databases_disabled": False, + "default_encoding": "iso-8859-1", + "default_fixed_font_size": 0, + "default_font_size": 0, + "developer_tools_disabled": False, + "dom_paste_disabled": False, + "drag_drop_disabled": False, + "encoding_detector_enabled": False, + "fantasy_font_family": "", + "file_access_from_file_urls_allowed": False, + "fixed_font_family": "", + "fullscreen_enabled": False, + "history_disabled": False, + "hyperlink_auditing_disabled": False, + "image_load_disabled": False, + "java_disabled": False, + "javascript_access_clipboard_disallowed": False, + "javascript_close_windows_disallowed": False, + "javascript_disabled": False, + "javascript_open_windows_disallowed": False, + "load_drops_disabled": False, + "local_storage_disabled": False, + "minimum_font_size": 0, + "minimum_logical_font_size": 0, + "page_cache_disabled": False, + "plugins_disabled": False, + "remote_fonts_disabled": False, + "sans_serif_font_family": "", + "serif_font_family": "", + "shrink_standalone_images_to_fit": False, + "site_specific_quirks_disabled": False, + "standard_font_family": "", + "tab_to_links_disabled": False, + "text_area_resize_disabled": False, + "universal_access_from_file_urls_allowed": False, + "user_style_sheet_enabled": False, + "user_style_sheet_location": "", + "web_security_disabled": False, + "webgl_disabled": False, + "xss_auditor_enabled": False, +} + +# +# Browser object. +# + +class Browser: + + def CanGoBack(self): + return False + + def CanGoForward(self): + return False + + def ClearHistory(self): + return None + + def CloseBrowser(self): + return None + + def CloseDevTools(self): + return None + + def Find(self, searchID, searchText, forward, matchCase, findNext): + return None + + def GetClientCallback(self, name): + return callback + + def GetClientCallbacksDict(self): + return {} + + def GetFocusedFrame(self): + return Frame() + + def GetFrame(self): + return Frame() + + def GetFrameNames(self): + return ["", ""] + + def GetIdentifier(self): + return 0 + + def GetImage(self, paintElementType, width, height): + return PaintBuffer() + + def GetJavascriptBindings(self): + return JavascriptBindings() + + def GetMainFrame(self): + return Frame() + + def GetOpenerWindowHandle(self): + return 0 + + def GetOuterWindowHandle(self): + return 0 + + def GetSize(self, paintElementType): + return (0,0,) + + def GetUserData(self, key): + return None + + def GetWindowID(self): + return windowID + + def GetWindowHandle(self): + return 0 + + def GetZoomLevel(self): + return 0.0 + + def GoBack(self): + return None + + def GoForward(self): + return None + + def HasDocument(self): + return False + + def HidePopup(self): + return None + + def Invalidate(self, dirtyRect): + return None + + def IsFullscreen(self): + return False + + def IsPopup(self): + return False + + def IsPopupVisible(self): + return False + + def IsWindowRenderingDisabled(self): + return False + + def Reload(self): + return None + + def ReloadIgnoreCache(self): + return None + + def SendKeyEvent(self, keyType, keyInfo, modifiers): + return None + + def SendMouseClickEvent(self, x, y, mouseButtonType, mouseUp, clickCount): + return None + + def SendMouseMoveEvent(self, x, y, mouseLeave): + return None + + def SendMouseWheelEvent(self, x, y, deltaX, deltaY): + return None + + def SendFocusEvent(self, setFocus): + return None + + def SendCaptureLostEvent(self): + return None + + def SetClientCallback(self, name, callback): + return None + + def SetClientHandler(self, clientHandler): + return None + + def SetFocus(self, enable): + return None + + def SetJavascriptBindings(self, javascriptBindings): + return None + + def SetSize(self, paintElementType, width, height): + return None + + def SetZoomLevel(self, zoomLevel): + return None + + def SetUserData(self, key, value): + return None + + def ShowDevTools(self): + return None + + def StopLoad(self): + return None + + def StopFinding(self, clearSelection): + return None + + def ToggleFullscreen(self): + return None + +# +# Frame object. +# + +class Frame: + + def Copy(self): + return None + + def Cut(self): + return None + + def Delete(self): + return None + + def ExecuteJavascript(self, jsCode, scriptUrl=None, startLine=None): + return None + + def GetIdentifier(self): + return 0 + + def GetName(self): + return "" + + def GetProperty(self, name): + return mixed + + def GetSource(self): + return "" + + def GetText(self): + return "" + + def GetUrl(self): + return "" + + def IsFocused(self): + return False + + def IsMain(self): + return False + + def LoadString(self, value, url): + return None + + def LoadUrl(self, url): + return None + + def Paste(self): + return None + + def Print(self): + return None + + def Redo(self): + return None + + def SelectAll(self): + return None + + def SetProperty(self, name, value): + return None + + def Undo(self): + return None + + def ViewSource(self): + return None + +class Response: + + def GetStatus(self): + return 0 + + def SetStatus(self, status): + return None + + def GetStatusText(self): + return "" + + def SetStatusText(self, statusText): + return None + + def GetMimeType(self): + return "" + + def SetMimeType(self, mimeType): + return None + + def GetHeader(self, name): + return "" + + def GetHeaderMap(self): + return {} + + def GetHeaderMultimap(self): + return [("","")] + + def SetHeaderMap(self, headerMap={}): + return None + + def SetHeaderMultimap(self, headerMultimap=[]): + return None + +class PaintBuffer: + + def GetIntPointer(self): + return 0 + + def GetString(self, mode="bgra", origin="top-left"): + return "" + +class JavascriptBindings: + + def __init__(self, bindToFrames=False, bindToPopups=False): + return None + + def IsValueAllowed(self, value): + return False + + def Rebind(self): + return None + + def SetFunction(self, name, func): + return None + + def SetObject(self, name, obj): + return None + + def SetProperty(self, name, value): + return None + +class JavascriptCallback: + + def Call(self, param1, param2, param3_etc): + return mixed + + def GetName(self): + return name + +class WindowUtils: + + @staticmethod + def OnSetFocus(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnSize(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnEraseBackground(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def SetTitle(pyBrowser, pyTitle): + return None + + @staticmethod + def SetIcon(pyBrowser, icon="inherit"): + return None + +# +# DisplayHandler. +# + +# statusType constants (OnStatusMessage). +STATUSTYPE_TEXT = 0 +STATUSTYPE_MOUSEOVER_URL = 0 +STATUSTYPE_KEYBOARD_FOCUS_URL = 0 + +def DisplayHandler_OnAddressChange(browser, frame, url): + return None + +def DisplayHandler_OnConsoleMessage(browser, message, source, line): + return False + +def DisplayHandler_OnContentsSizeChange(browser, frame, width, height): + return None + +def DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward): + return None + +def DisplayHandler_OnStatusMessage(browser, text, statusType): + return None + +def DisplayHandler_OnTitleChange(browser, title): + return None + +def DisplayHandler_OnTooltip(browser, text_out=[""]): + return False + +# +# KeyboardHandler. +# + +def KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript): + return False + +# keyCode constants (OnKeyEvent). +VK_0=0x30 +VK_1=0x31 +VK_2=0x32 +VK_3=0x33 +VK_4=0x34 +VK_5=0x35 +VK_6=0x36 +VK_7=0x37 +VK_8=0x38 +VK_9=0x39 +VK_A=0x041 +VK_B=0x042 +VK_C=0x043 +VK_D=0x044 +VK_E=0x045 +VK_F=0x046 +VK_G=0x047 +VK_H=0x048 +VK_I=0x049 +VK_J=0x04A +VK_K=0x04B +VK_L=0x04C +VK_M=0x04D +VK_N=0x04E +VK_O=0x04F +VK_P=0x050 +VK_Q=0x051 +VK_R=0x052 +VK_S=0x053 +VK_T=0x054 +VK_U=0x055 +VK_V=0x056 +VK_W=0x057 +VK_X=0x058 +VK_Y=0x059 +VK_Z=0x05A +VK_F1=0x70 +VK_F2=0x71 +VK_F3=0x72 +VK_F4=0x73 +VK_F5=0x74 +VK_F6=0x75 +VK_F7=0x76 +VK_F8=0x77 +VK_F9=0x78 +VK_F10=0x79 +VK_F11=0x7A +VK_F12=0x7B +VK_F13=0x7C +VK_F14=0x7D +VK_F15=0x7E +VK_F16=0x7F +VK_F17=0x80 +VK_F18=0x81 +VK_F19=0x82 +VK_F20=0x83 +VK_F21=0x84 +VK_F22=0x85 +VK_F23=0x86 +VK_F24=0x87 +VK_LSHIFT=0xA0 +VK_RSHIFT=0xA1 +VK_LCONTROL=0xA2 +VK_RCONTROL=0xA3 +VK_LMENU=0xA4 +VK_RMENU=0xA5 +VK_BACK=0x08 +VK_TAB=0x09 +VK_SPACE=0x20 +VK_PRIOR=0x21 +VK_NEXT=0x22 +VK_END=0x23 +VK_HOME=0x24 +VK_LEFT=0x25 +VK_UP=0x26 +VK_RIGHT=0x27 +VK_DOWN=0x28 +VK_SELECT=0x29 +VK_PRINT=0x2A +VK_EXECUTE=0x2B +VK_SNAPSHOT=0x2C +VK_INSERT=0x2D +VK_DELETE=0x2E +VK_HELP=0x2F +VK_SHIFT=0x10 +VK_CONTROL=0x11 +VK_MENU=0x12 +VK_PAUSE=0x13 +VK_CAPITAL=0x14 +VK_CLEAR=0x0C +VK_RETURN=0x0D +VK_ESCAPE=0x1B +VK_LWIN=0x5B +VK_RWIN=0x5C +VK_APPS=0x5D +VK_SLEEP=0x5F +VK_NUMPAD0=0x60 +VK_NUMPAD1=0x61 +VK_NUMPAD2=0x62 +VK_NUMPAD3=0x63 +VK_NUMPAD4=0x64 +VK_NUMPAD5=0x65 +VK_NUMPAD6=0x66 +VK_NUMPAD7=0x67 +VK_NUMPAD8=0x68 +VK_NUMPAD9=0x69 +VK_BROWSER_BACK=0xA6 +VK_BROWSER_FORWARD=0xA7 +VK_BROWSER_REFRESH=0xA8 +VK_BROWSER_STOP=0xA9 +VK_BROWSER_SEARCH=0xAA +VK_BROWSER_FAVORITES=0xAB +VK_BROWSER_HOME=0xAC +VK_VOLUME_MUTE=0xAD +VK_VOLUME_DOWN=0xAE +VK_VOLUME_UP=0xAF +VK_MEDIA_NEXT_TRACK=0xB0 +VK_MEDIA_PREV_TRACK=0xB1 +VK_MEDIA_STOP=0xB2 +VK_MEDIA_PLAY_PAUSE=0xB3 +VK_LAUNCH_MAIL=0xB4 +VK_LAUNCH_MEDIA_SELECT=0xB5 +VK_LAUNCH_APP1=0xB6 +VK_LAUNCH_APP2=0xB7 +VK_MULTIPLY=0x6A +VK_ADD=0x6B +VK_SEPARATOR=0x6C +VK_SUBTRACT=0x6D +VK_DECIMAL=0x6E +VK_DIVIDE=0x6F +VK_NUMLOCK=0x90 +VK_SCROLL=0x91 +VK_LBUTTON=0x01 +VK_RBUTTON=0x02 +VK_CANCEL=0x03 +VK_MBUTTON=0x04 +VK_XBUTTON1=0x05 +VK_XBUTTON2=0x06 +VK_KANA=0x15 +VK_HANGEUL=0x15 +VK_HANGUL=0x15 +VK_JUNJA=0x17 +VK_FINAL=0x18 +VK_HANJA=0x19 +VK_KANJI=0x19 +VK_CONVERT=0x1C +VK_NONCONVERT=0x1D +VK_ACCEPT=0x1E +VK_MODECHANGE=0x1F +VK_PROCESSKEY=0xE5 +VK_PACKET=0xE7 +VK_ICO_HELP=0xE3 +VK_ICO_00=0xE4 +VK_ICO_CLEAR=0xE6 + +# eventType constants (OnKeyEvent). +KEYEVENT_RAWKEYDOWN = 0 +KEYEVENT_KEYDOWN = 0 +KEYEVENT_KEYUP = 0 +KEYEVENT_CHAR = 0 + +# Constants for checking modifiers param (OnKeyEvent), for use with IsKeyModifier() function. +KEY_NONE = 0 +KEY_SHIFT = 0 +KEY_CTRL = 0 +KEY_ALT = 0 +KEY_META = 0 +KEY_KEYPAD = 0 + +# +# LoadHandler. +# + +def LoadHandler_OnLoadEnd(browser, frame, httpStatusCode): + return None + +def LoadHandler_OnLoadError(browser, frame, errorCode, failedUrl, errorText_out=[""]): + return False + +def LoadHandler_OnLoadStart(browser, frame): + return None + +# errorCode constants (OnLoadError). +ERR_FAILED = 0 +ERR_ABORTED = 0 +ERR_INVALID_ARGUMENT = 0 +ERR_INVALID_HANDLE = 0 +ERR_FILE_NOT_FOUND = 0 +ERR_TIMED_OUT = 0 +ERR_FILE_TOO_BIG = 0 +ERR_UNEXPECTED = 0 +ERR_ACCESS_DENIED = 0 +ERR_NOT_IMPLEMENTED = 0 +ERR_CONNECTION_CLOSED = 0 +ERR_CONNECTION_RESET = 0 +ERR_CONNECTION_REFUSED = 0 +ERR_CONNECTION_ABORTED = 0 +ERR_CONNECTION_FAILED = 0 +ERR_NAME_NOT_RESOLVED = 0 +ERR_INTERNET_DISCONNECTED = 0 +ERR_SSL_PROTOCOL_ERROR = 0 +ERR_ADDRESS_INVALID = 0 +ERR_ADDRESS_UNREACHABLE = 0 +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = 0 +ERR_TUNNEL_CONNECTION_FAILED = 0 +ERR_NO_SSL_VERSIONS_ENABLED = 0 +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = 0 +ERR_SSL_RENEGOTIATION_REQUESTED = 0 +ERR_CERT_COMMON_NAME_INVALID = 0 +ERR_CERT_DATE_INVALID = 0 +ERR_CERT_AUTHORITY_INVALID = 0 +ERR_CERT_CONTAINS_ERRORS = 0 +ERR_CERT_NO_REVOCATION_MECHANISM = 0 +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 0 +ERR_CERT_REVOKED = 0 +ERR_CERT_INVALID = 0 +ERR_CERT_END = 0 +ERR_INVALID_URL = 0 +ERR_DISALLOWED_URL_SCHEME = 0 +ERR_UNKNOWN_URL_SCHEME = 0 +ERR_TOO_MANY_REDIRECTS = 0 +ERR_UNSAFE_REDIRECT = 0 +ERR_UNSAFE_PORT = 0 +ERR_INVALID_RESPONSE = 0 +ERR_INVALID_CHUNKED_ENCODING = 0 +ERR_METHOD_NOT_SUPPORTED = 0 +ERR_UNEXPECTED_PROXY_AUTH = 0 +ERR_EMPTY_RESPONSE = 0 +ERR_RESPONSE_HEADERS_TOO_BIG = 0 +ERR_CACHE_MISS = 0 +ERR_INSECURE_RESPONSE = 0 + +# +# RequestHandler. +# + +def RequestHandler_OnResourceRedirect(browser, oldUrl, newUrl_out=[""]): + return None + +def RequestHandler_OnResourceResponse(browser, url, response, filter_out=[None]): + return None + +def RequestHandler_OnProtocolExecution(browser, url, allowOSExecution_out=[False]): + return False + +def RequestHandler_GetAuthCredentials(browser, isProxy, host, port, realm, scheme, username_out=[""], password_out=[""]): + return False + +# navType constants (OnBeforeBrowse). +NAVTYPE_LINKCLICKED = 0 +NAVTYPE_FORMSUBMITTED = 0 +NAVTYPE_BACKFORWARD = 0 +NAVTYPE_RELOAD = 0 +NAVTYPE_FORMRESUBMITTED = 0 +NAVTYPE_OTHER = 0 +NAVTYPE_LINKDROPPED = 0 + +# +# JavascriptContextHandler +# + +def JavascriptContextHandler_OnUncaughtException(browser, frame, exception, stackTrace): + return None + +# +# LifespanHandler +# + +def LifespanHandler_DoClose(browser): + return False + +def LifespanHandler_OnAfterCreated(browser): + return None + +def LifespanHandler_OnBeforeClose(browser): + return None + +def LifespanHandler_RunModal(browser): + return False + +# +# RenderHandler +# + +PET_VIEW = 0 +PET_POPUP = 0 + +KEYTYPE_KEYUP = 0 +KEYTYPE_KEYDOWN = 0 +KEYTYPE_CHAR = 0 + +MOUSEBUTTON_LEFT = 0 +MOUSEBUTTON_MIDDLE = 0 +MOUSEBUTTON_RIGHT = 0 + +def RenderHandler_GetViewRect(browser, out_rect): + return False + +def RenderHandler_GetScreenRect(browser, out_rect): + return False + +def RenderHandler_GetScreenPoint(browser, viewX, viewY, out_screenCoordinates): + return False + +def RenderHandler_OnPopupShow(browser, show): + return None + +def RenderHandler_OnPopupSize(browser, rect): + return None + +def RenderHandler_OnPaint(browser, paintElementType, out_dirtyRects, + paintBuffer): + return None + +def RenderHandler_OnCursorChange(browser, cursor): + return None diff --git a/cefpython/cef1/linux/binaries_64bit/cefsimple.html b/cefpython/cef1/linux/binaries_64bit/cefsimple.html new file mode 100644 index 00000000..f46f773c --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/cefsimple.html @@ -0,0 +1,37 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Welcome to CEF Python - bindings for the Chromium Embedded Framework.

+ +Project's website: http://code.google.com/p/cefpython/
+Wiki documentation: http://code.google.com/p/cefpython/wiki/
+Support forum: https://groups.google.com/group/cefpython?hl=en
+ +

Google Search

+ +http://www.google.com/ + +

User agent

+ + + +

Popup

+ + + window.open('cefsimple.html') + +










+










+










+ + + diff --git a/cefpython/cef1/linux/binaries_64bit/chrome.pak b/cefpython/cef1/linux/binaries_64bit/chrome.pak new file mode 100644 index 00000000..567a768a Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/chrome.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/devtools_resources.pak b/cefpython/cef1/linux/binaries_64bit/devtools_resources.pak new file mode 100644 index 00000000..1b92eaa0 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/devtools_resources.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/libcef.so b/cefpython/cef1/linux/binaries_64bit/libcef.so new file mode 100755 index 00000000..de051ffb Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/libcef.so differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/am.pak b/cefpython/cef1/linux/binaries_64bit/locales/am.pak new file mode 100644 index 00000000..3749afe0 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/am.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ar.pak b/cefpython/cef1/linux/binaries_64bit/locales/ar.pak new file mode 100644 index 00000000..ea7f660e Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ar.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/bg.pak b/cefpython/cef1/linux/binaries_64bit/locales/bg.pak new file mode 100644 index 00000000..29c4cc32 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/bg.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/bn.pak b/cefpython/cef1/linux/binaries_64bit/locales/bn.pak new file mode 100644 index 00000000..6658c44e Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/bn.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ca.pak b/cefpython/cef1/linux/binaries_64bit/locales/ca.pak new file mode 100644 index 00000000..b5591db8 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ca.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/cs.pak b/cefpython/cef1/linux/binaries_64bit/locales/cs.pak new file mode 100644 index 00000000..47b46641 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/cs.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/da.pak b/cefpython/cef1/linux/binaries_64bit/locales/da.pak new file mode 100644 index 00000000..92752174 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/da.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/de.pak b/cefpython/cef1/linux/binaries_64bit/locales/de.pak new file mode 100644 index 00000000..9ea672bb Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/de.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/el.pak b/cefpython/cef1/linux/binaries_64bit/locales/el.pak new file mode 100644 index 00000000..addb3984 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/el.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/en-GB.pak b/cefpython/cef1/linux/binaries_64bit/locales/en-GB.pak new file mode 100644 index 00000000..239dc460 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/en-GB.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/en-US.pak b/cefpython/cef1/linux/binaries_64bit/locales/en-US.pak new file mode 100644 index 00000000..6acdf9dd Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/en-US.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/es-419.pak b/cefpython/cef1/linux/binaries_64bit/locales/es-419.pak new file mode 100644 index 00000000..889e5a9b Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/es-419.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/es.pak b/cefpython/cef1/linux/binaries_64bit/locales/es.pak new file mode 100644 index 00000000..d771963e Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/es.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/et.pak b/cefpython/cef1/linux/binaries_64bit/locales/et.pak new file mode 100644 index 00000000..0775bd23 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/et.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/fa.pak b/cefpython/cef1/linux/binaries_64bit/locales/fa.pak new file mode 100644 index 00000000..7d8c8578 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/fa.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/fi.pak b/cefpython/cef1/linux/binaries_64bit/locales/fi.pak new file mode 100644 index 00000000..7edb1bf9 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/fi.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/fil.pak b/cefpython/cef1/linux/binaries_64bit/locales/fil.pak new file mode 100644 index 00000000..ab55920c Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/fil.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/fr.pak b/cefpython/cef1/linux/binaries_64bit/locales/fr.pak new file mode 100644 index 00000000..ea53e029 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/fr.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/gu.pak b/cefpython/cef1/linux/binaries_64bit/locales/gu.pak new file mode 100644 index 00000000..9e984316 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/gu.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/he.pak b/cefpython/cef1/linux/binaries_64bit/locales/he.pak new file mode 100644 index 00000000..e9f407e5 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/he.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/hi.pak b/cefpython/cef1/linux/binaries_64bit/locales/hi.pak new file mode 100644 index 00000000..45d08355 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/hi.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/hr.pak b/cefpython/cef1/linux/binaries_64bit/locales/hr.pak new file mode 100644 index 00000000..e20580e6 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/hr.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/hu.pak b/cefpython/cef1/linux/binaries_64bit/locales/hu.pak new file mode 100644 index 00000000..7d2c2f24 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/hu.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/id.pak b/cefpython/cef1/linux/binaries_64bit/locales/id.pak new file mode 100644 index 00000000..6d9e4510 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/id.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/it.pak b/cefpython/cef1/linux/binaries_64bit/locales/it.pak new file mode 100644 index 00000000..0d10cb60 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/it.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ja.pak b/cefpython/cef1/linux/binaries_64bit/locales/ja.pak new file mode 100644 index 00000000..b29e7daa Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ja.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/kn.pak b/cefpython/cef1/linux/binaries_64bit/locales/kn.pak new file mode 100644 index 00000000..316496f0 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/kn.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ko.pak b/cefpython/cef1/linux/binaries_64bit/locales/ko.pak new file mode 100644 index 00000000..86b0841d Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ko.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/lt.pak b/cefpython/cef1/linux/binaries_64bit/locales/lt.pak new file mode 100644 index 00000000..be6444f2 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/lt.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/lv.pak b/cefpython/cef1/linux/binaries_64bit/locales/lv.pak new file mode 100644 index 00000000..ca37399c Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/lv.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ml.pak b/cefpython/cef1/linux/binaries_64bit/locales/ml.pak new file mode 100644 index 00000000..25782a80 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ml.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/mr.pak b/cefpython/cef1/linux/binaries_64bit/locales/mr.pak new file mode 100644 index 00000000..253c6633 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/mr.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ms.pak b/cefpython/cef1/linux/binaries_64bit/locales/ms.pak new file mode 100644 index 00000000..3bfcea5c Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ms.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/nb.pak b/cefpython/cef1/linux/binaries_64bit/locales/nb.pak new file mode 100644 index 00000000..1868484f Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/nb.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/nl.pak b/cefpython/cef1/linux/binaries_64bit/locales/nl.pak new file mode 100644 index 00000000..92303e44 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/nl.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/pl.pak b/cefpython/cef1/linux/binaries_64bit/locales/pl.pak new file mode 100644 index 00000000..af8e3100 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/pl.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/pt-BR.pak b/cefpython/cef1/linux/binaries_64bit/locales/pt-BR.pak new file mode 100644 index 00000000..9bfea0b4 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/pt-BR.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/pt-PT.pak b/cefpython/cef1/linux/binaries_64bit/locales/pt-PT.pak new file mode 100644 index 00000000..e0b2a9fb Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/pt-PT.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ro.pak b/cefpython/cef1/linux/binaries_64bit/locales/ro.pak new file mode 100644 index 00000000..213b3f47 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ro.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ru.pak b/cefpython/cef1/linux/binaries_64bit/locales/ru.pak new file mode 100644 index 00000000..b2fd1200 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ru.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/sk.pak b/cefpython/cef1/linux/binaries_64bit/locales/sk.pak new file mode 100644 index 00000000..127c0a07 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/sk.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/sl.pak b/cefpython/cef1/linux/binaries_64bit/locales/sl.pak new file mode 100644 index 00000000..d5ab0933 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/sl.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/sr.pak b/cefpython/cef1/linux/binaries_64bit/locales/sr.pak new file mode 100644 index 00000000..e9853962 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/sr.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/sv.pak b/cefpython/cef1/linux/binaries_64bit/locales/sv.pak new file mode 100644 index 00000000..37a6eca3 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/sv.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/sw.pak b/cefpython/cef1/linux/binaries_64bit/locales/sw.pak new file mode 100644 index 00000000..13c0c0f2 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/sw.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/ta.pak b/cefpython/cef1/linux/binaries_64bit/locales/ta.pak new file mode 100644 index 00000000..322af150 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/ta.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/te.pak b/cefpython/cef1/linux/binaries_64bit/locales/te.pak new file mode 100644 index 00000000..c67cf997 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/te.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/th.pak b/cefpython/cef1/linux/binaries_64bit/locales/th.pak new file mode 100644 index 00000000..7813f91c Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/th.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/tr.pak b/cefpython/cef1/linux/binaries_64bit/locales/tr.pak new file mode 100644 index 00000000..1867524d Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/tr.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/uk.pak b/cefpython/cef1/linux/binaries_64bit/locales/uk.pak new file mode 100644 index 00000000..c0c5c758 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/uk.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/vi.pak b/cefpython/cef1/linux/binaries_64bit/locales/vi.pak new file mode 100644 index 00000000..ec74997e Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/vi.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/zh-CN.pak b/cefpython/cef1/linux/binaries_64bit/locales/zh-CN.pak new file mode 100644 index 00000000..d82fd560 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/zh-CN.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/locales/zh-TW.pak b/cefpython/cef1/linux/binaries_64bit/locales/zh-TW.pak new file mode 100644 index 00000000..10aa9001 Binary files /dev/null and b/cefpython/cef1/linux/binaries_64bit/locales/zh-TW.pak differ diff --git a/cefpython/cef1/linux/binaries_64bit/pygtk_.py b/cefpython/cef1/linux/binaries_64bit/pygtk_.py new file mode 100644 index 00000000..77141a51 --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/pygtk_.py @@ -0,0 +1,191 @@ +# An example of embedding CEF browser in PyGTK on Linux. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython1 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import re + +def GetApplicationPath(file=None): + import re, os, platform + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + vbox = None + + def __init__(self): + + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=600, height=400) + self.mainWindow.set_title('PyGTK CEF example') + self.mainWindow.realize() + + self.vbox = gtk.VBox(False, 0) + self.vbox.pack_start(self.CreateMenu(), False, False, 0) + self.mainWindow.add(self.vbox) + + m = re.search("GtkVBox at 0x(\w+)", str(self.vbox)) + hexID = m.group(1) + windowID = int(hexID, 16) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # Flash will crash app in CEF 1 on Linux, setting + # plugins_disabled to True. + browserSettings={"plugins_disabled": True}, + navigateUrl="file://"+GetApplicationPath("cefsimple.html")) + + # Must be show_all() for VBox otherwise browser doesn't + # appear when you just call show(). + self.vbox.show() + + self.mainWindow.show() + gobject.timeout_add(10, self.OnTimer) + + def CreateMenu(self): + + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + + about = gtk.MenuItem('About') + about.show() + aboutmenu = gtk.Menu() + item = gtk.MenuItem('CEF Python') + aboutmenu.append(item) + item.show() + about.set_submenu(aboutmenu) + + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + + return menubar + + def OnWidgetClick(self, widget, data): + + self.mainWindow.get_window().focus() + + def OnTimer(self): + + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + + # This function is currently not called by any of code, + # but if you would like for browser to have automatic focus + # add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + self.browser.SetFocus(True) + + def OnExit(self, widget, data=None): + + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + + version = '.'.join(map(str, list(gtk.gtk_version))) + print('GTK version: %s' % version) + + sys.excepthook = ExceptHook + cefpython.g_debug = True + cefpython.g_debugFile = GetApplicationPath("debug.log") + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory() + } + cefpython.Initialize(settings) + + gobject.threads_init() # timer for messageloop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef1/linux/binaries_64bit/wxpython.html b/cefpython/cef1/linux/binaries_64bit/wxpython.html new file mode 100644 index 00000000..ff674443 --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/wxpython.html @@ -0,0 +1,172 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Use mouse context menu to go Back/Forward in history navigation. + + + +

Google Search

+http://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('wxpython.html') + + + + +

RequestHandler tests

+ +

See messages in the console.

+ +OnBeforeBrowse() - navigate to see message: +wxpython.html +

+ +OnBeforeBrowse() / OnBeforeResourceLoad() - test request.GetPostData() +and request.SetPostData(): +submit a form: + + https://accounts.google.com/ServiceLogin, +upload a file: + + http://encodable.com/uploaddemo/ +

+ +OnBeforeResourceLoad() - try loading nonexistent css file locally: + + LoadCssFile('nonexistent.css') + +

+ +OnBeforeResourceLoad() - try replacing a resource on the fly: + + LoadCssFile('replace-on-the-fly.css') +(css content: body { color: red; }) +

+ +OnResourceRedirect() - try loading this url: + + http://tinyurl.com/google404redirect +

+ +OnResourceResponse() - try loading nonexistent css file via http: + + LoadCssFile('http://www.google.com/404.css') +

+ +OnResourceResponse() - try filtering content of the resource: + + LoadCssFile('content-filter/replace-on-the-fly.css') +(new css content: body { color: green; } and body h3 { color: orange; } ) +

+ + + + + +

WebRequest test

+ +See the console for messages.
+ + + external.WebRequest('https://code.google.com/robots.txt') + +

Frame.CallFunction() test

+ + + + external.DoCallFunction() + + + + +

Cookie tests

+ +See messages in the console. +

+ +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. Visit + + http://www.html-kit.com/tools/cookietester/ and set some cookie, +then go back to this page using the context menu and open a + + new popup window, the cookie should not appear in the popup browser window. +

+ +CookieManager.VisitAllCookies() - visit all cookies: +external.VisitAllCookies() +(note: visit some http:// webpage first, otherwise cookie manager is not +yet created) +

+ +CookieManager.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +- visit a subset of cookies given the url, test: +external.VisitUrlCookies() +

+ +CookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + {name:"Created_Via_Python", value:"yeah really"}) - create the cookie: + external.SetCookie() +

+ +CookieManager.DeleteCookies() - delete the single cookie previously created +via SetCookie(): + external.DeleteCookies() +

+ + + + +

DragHandler test

+ +Try dragging a file, or a text/html fragment to the browser window +and look for the messages in the console. In the wxpython.py script see +ClientHandler.OnDragStart() and OnDragEnter(). + + + + +

DownloadHandler test

+ +Try downloading this file (838 KiB):
+ + http://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip +
+See messages in the console. +The file will be saved in the ./downloads/ directory. + + + + + + diff --git a/cefpython/cef1/linux/binaries_64bit/wxpython.py b/cefpython/cef1/linux/binaries_64bit/wxpython.py new file mode 100644 index 00000000..cac0def2 --- /dev/null +++ b/cefpython/cef1/linux/binaries_64bit/wxpython.py @@ -0,0 +1,529 @@ +# An example of embedding CEF browser in wxPython on Linux. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython1 import cefpython + +import wx +import time +import re +import uuid + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + idleCount = 0 + mainPanel = None + + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython example', size=(800,600)) + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + self.mainPanel = wx.Panel(self) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.mainPanel.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # Flash will crash app in CEF 1 on Linux, setting + # plugins_disabled to True. + browserSettings={"plugins_disabled": True}, + navigateUrl="file://"+GetApplicationPath("wxpython.html")) + + self.browser.SetClientHandler(ClientHandler()) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=False) + jsBindings.SetObject("external", JavascriptBindings(self.browser)) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + self.browser.CloseBrowser() + self.Destroy() + + def OnIdle(self, event): + # self.idleCount += 1 + # print("wxpython.py: OnIdle() %d" % self.idleCount) + cefpython.MessageLoopWork() + +class JavascriptBindings: + mainBrowser = None + webRequest = None + webRequestId = 0 + cookieVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def WebRequest(self, url): + request = cefpython.Request.CreateRequest() + request.SetUrl(url) + webRequestClient = WebRequestClient() + # Must keep the reference otherwise WebRequestClient + # callbacks won't be called. + self.webRequest = cefpython.WebRequest.CreateWebRequest(request, + webRequestClient) + + def DoCallFunction(self): + self.mainBrowser.GetMainFrame().CallFunction( + "MyFunction", "abc", 12, [1,2,3], {"qwe": 456, "rty": 789}) + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\nCookie created! Visit html-kit cookietester to see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\nCookie deleted! Visit html-kit cookietester to see the result") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\nCookieVisitor.Visit(): total cookies: %s" % total) + print("\nCookieVisitor.Visit(): cookie:") + print(cookie.Get()) + # True to continue visiting cookies + return True + +class WebRequestClient: + def OnStateChange(self, webRequest, state): + stateName = "unknown" + for key, value in cefpython.WebRequest.State.iteritems(): + if value == state: + stateName = key + print("\nWebRequestClient::OnStateChange(): state = %s" % stateName) + + def OnRedirect(self, webRequest, request, response): + print("\nWebRequestClient::OnRedirect(): url = %s" % ( + request.GetUrl()[:80])) + + def OnHeadersReceived(self, webRequest, response): + print("\nWebRequestClient::OnHeadersReceived(): headers = %s" % ( + response.GetHeaderMap())) + + def OnProgress(self, webRequest, bytesSent, totalBytesToBeSent): + print("\nWebRequestClient::OnProgress(): bytesSent = %s, " + "totalBytesToBeSent = %s" % (bytesSent, totalBytesToBeSent)) + + def OnData(self, webRequest, data): + print("\nWebRequestClient::OnData(): data:") + print("-" * 60) + print(data) + print("-" * 60) + + def OnError(self, webRequest, errorCode): + print("\nWebRequestClient::OnError(): errorCode = %s" % errorCode) + +class ContentFilterHandler: + def OnData(self, data, substitute_data): + if data == "body { color: red; }": + substitute_data.SetData("body { color: green; }") + + def OnDrain(self, remainder): + remainder.SetData("body h3 { color: orange; }") + +class ClientHandler: + # -------------------------------------------------------------------------- + # RequestHandler + # -------------------------------------------------------------------------- + contentFilter = None + + def OnBeforeBrowse(self, browser, frame, request, navType, isRedirect): + # - frame.GetUrl() returns current url + # - request.GetUrl() returns new url + # - Return true to cancel the navigation or false to allow + # the navigation to proceed. + # - Modifying headers or post data can be done only in + # OnBeforeResourceLoad() + print("\nOnBeforeBrowse(): request.GetUrl() = %s, " + "request.GetHeaderMap(): %s" % ( + request.GetUrl()[:80], request.GetHeaderMap())) + if request.GetMethod() == "POST": + print("\nOnBeforeBrowse(): POST data: %s" % ( + request.GetPostData())) + + def OnBeforeResourceLoad(self, browser, request, redirectUrl, + streamReader, response, loadFlags): + print("\nOnBeforeResourceLoad(): request.GetUrl() = %s" % ( + request.GetUrl()[:80])) + if request.GetMethod() == "POST": + if request.GetUrl().startswith( + "https://accounts.google.com/ServiceLogin"): + postData = request.GetPostData() + postData["Email"] = "--changed via python" + request.SetPostData(postData) + print("\nOnBeforeResourceLoad(): modified POST data: %s" % ( + request.GetPostData())) + if request.GetUrl().endswith("replace-on-the-fly.css"): + print("\nOnBeforeResourceLoad(): replacing css on the fly") + response.SetStatus(200) + response.SetStatusText("OK") + response.SetMimeType("text/css") + streamReader.SetData("body { color: red; }") + + def OnResourceRedirect(self, browser, oldUrl, newUrl): + print("\nOnResourceRedirect(): oldUrl: %s, newUrl: %s" % ( + oldUrl, newUrl[0])) + + def OnResourceResponse(self, browser, url, response, contentFilter): + print("\nOnResourceResponse(): url = %s, headers = %s" % ( + url[:80], response.GetHeaderMap())) + if url.endswith("content-filter/replace-on-the-fly.css"): + print("\nOnResourceResponse(): setting contentFilter handler") + contentFilter.SetHandler(ContentFilterHandler()) + # Must keep the reference to contentFilter otherwise + # ContentFilterHandler callbacks won't be called. + self.contentFilter = contentFilter + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + cookieManager = cefpython.CookieManager.CreateManager("") + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + # -------------------------------------------------------------------------- + # DragHandler + # -------------------------------------------------------------------------- + + def OnDragStart(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragStart(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + return False + + def OnDragEnter(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragEnter(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + return False + + # -------------------------------------------------------------------------- + # DownloadHandler + # -------------------------------------------------------------------------- + + downloadHandler = None + + def GetDownloadHandler(self, browser, mimeType, filename, contentLength): + # Close the browser window if it is a popup with + # no other document contents. + if browser.IsPopup() and not browser.HasDocument(): + browser.CloseBrowser() + # The reference to DownloadHandler must be kept alive + # while download proceeds. + if self.downloadHandler and self.downloadHandler.downloading: + print("\nDownload is already in progress") + return False + self.downloadHandler = DownloadHandler(mimeType, filename, + contentLength) + return self.downloadHandler + +class DownloadHandler: + mimeType = "" + filename = "" + contentLength = -1 # -1 means that file size was not provided. + fp = None + downloadsDir = "./downloads" + alreadyDownloaded = 0 + downloading = False + + def __init__(self, mimeType, filename, contentLength): + self.downloading = True + if not os.path.exists(self.downloadsDir): + os.mkdir(self.downloadsDir) + filename = filename.strip() + if not len(filename): + filename = self.GetUniqueFilename() + filename = self.GetSafeFilename(filename) + print("\nDownloadHandler() created") + print("mimeType: %s" % mimeType) + print("filename: %s" % filename) + print("contentLength: %s" % contentLength) + # Append ".downloading" to the filename, in OnComplete() + # when download finishes get rid of this extension. + filename += ".downloading" + if os.path.exists(self.downloadsDir+"/"+filename): + # If the last download did not succeed, the + # "xxx.downloading" might still be there. + os.remove(self.downloadsDir+"/"+filename) + self.mimeType = mimeType + self.filename = filename + self.contentLength = contentLength + self.fp = open(self.downloadsDir+"/"+filename, "wb") + + def GetSafeFilename(self, filename): + # TODO: + # - remove any unsafe characters (".." or "/" or "\" and + # others), the safest way is to have a regexp with a list + # safe characters. The dots ".." is a special case that + # needs to be treated separately. + if os.path.exists(self.downloadsDir+"/"+filename): + filename = self.GetUniqueFilename()[:4]+"_"+filename + assert not os.path.exists(self.downloadsDir+"/"+filename), ( + "File aready exists") + return filename + + def GetUniqueFilename(self): + # The filename may be empty, in that case generate + # an unique name. + # TODO: + # - guess the extension using the mimeType (but mimeType + # may also be empty), "text/css" => ".css". + return str(uuid.uuid4()).replace("-", "")[:16] + + def OnData(self, data): + # TODO: display progress in percentage or/and KiB/MiB. + if self.alreadyDownloaded == 0: + sys.stdout.write("Download progress: ") + sys.stdout.write(".") + sys.stdout.flush() + self.alreadyDownloaded += len(data) + self.fp.write(data) + # time.sleep(1) # Let's make the progress a bit slower (if cached) + # Return True to continue receiving data, False to cancel. + return True + + def OnComplete(self): + sys.stdout.write("\n") + sys.stdout.flush() + self.fp.close() + currentFile = self.downloadsDir+"/"+self.filename + newFilename = re.sub(".downloading$", "", self.filename) + os.rename(self.downloadsDir+"/"+self.filename, + self.downloadsDir+"/"+newFilename) + self.downloading = False + print("\nDownload complete!") + print("Total downloaded: %s" % self.PrettyBytes( + self.alreadyDownloaded)) + print("See the 'downloads' directory.") + + def PrettyBytes(self, bytes): + KiB = 1024 + return "%.3g KiB" % (bytes / KiB) + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("wxpython.py: OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +if __name__ == '__main__': + sys.excepthook = ExceptHook + cefpython.g_debug = True + cefpython.g_debugFile = GetApplicationPath("debug.log") + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory() + } + cefpython.Initialize(settings) + + print('wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + + cefpython.Shutdown() diff --git a/cefpython/cef1/linux/compile.py b/cefpython/cef1/linux/compile.py new file mode 100755 index 00000000..f7de51fc --- /dev/null +++ b/cefpython/cef1/linux/compile.py @@ -0,0 +1,127 @@ +import sys +import os +import glob +import shutil +import subprocess +import platform + +# This will not show "Segmentation fault" error message: +# | subprocess.call(["python", "./wxpython.py"]) +# You need to call it with shell=True for this kind of +# error message to be shown: +# | subprocess.call("python wxpython.py", shell=True) + +# How to debug: +# 1. Install "python-dbg" package +# 2. Install "python-wxgtk2.8-dbg" package +# 3. Run "python compile.py debug" +# 4. In cygdb type "cy run" +# 5. To display debug backtrace type "cy bt" +# 6. More commands: http://docs.cython.org/src/userguide/debugging.html + +if len(sys.argv) > 1 and sys.argv[1] == "debug": + DEBUG = True + print("DEBUG mode On") +else: + DEBUG = False + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +PYVERSION = str(sys.version_info[0])+str(sys.version_info[1]) +print("PYVERSION = %s" % PYVERSION) +print("BITS = %s" % BITS) + +print("Compiling C++ projects") + +# Need to allow continuing even when make fails, as it may +# fail because the "public" function declaration is not yet +# in "cefpython.h", but for it to be generated we need to run +# cython compiling, so in this case you continue even when make +# fails and then run the compile.py script again and this time +# make should succeed. + +os.chdir("./../../cpp_utils/") +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit() + +os.chdir("./../cef1/client_handler/") +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit() + +os.chdir("./../v8function_handler/") +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit() + +os.chdir("./../linux/") + +try: + os.remove("./binaries_%s/cefpython_py%s.so" % (BITS, PYVERSION)) +except OSError: + pass + +try: + os.remove("./setup/cefpython_py%s.so" % PYVERSION) + os.remove("./setup/cefpython_py%s_d.so" % PYVERSION) +except OSError: + pass + +pyx_files = glob.glob("./setup/*.pyx") +for f in pyx_files: + os.remove(f) + +try: + shutil.rmtree("./setup/build") +except OSError: + pass + +os.chdir("./setup") + +ret = subprocess.call("python fix_includes.py", shell=True) +if ret != 0: + sys.exit("ERROR") + +if DEBUG: + ret = subprocess.call("python-dbg setup.py build_ext --inplace" + " --cython-gdb", shell=True) +else: + ret = subprocess.call("python setup.py build_ext --inplace", shell=True) + +if DEBUG: + shutil.rmtree("./../binaries_%s/cython_debug/" % BITS, ignore_errors=True) + shutil.copytree("./cython_debug/", "./../binaries_%s/cython_debug/" % BITS) + +os.chdir("../") + +oldpyxfiles = glob.glob("./setup/*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +if ret != 0: + sys.exit("ERROR") + +if DEBUG: + os.rename("./setup/cefpython_py%s_d.so" % PYVERSION, "./binaries_%s/cefpython_py%s.so" % (BITS, PYVERSION)) +else: + os.rename("./setup/cefpython_py%s.so" % PYVERSION, "./binaries_%s/cefpython_py%s.so" % (BITS, PYVERSION)) + +shutil.copyfile("./../../cef1_api.py", "./binaries_%s/cefpython_py%s.py" % (BITS, PYVERSION)) + +print("DONE") + +os.chdir("./binaries_%s" % BITS) +if DEBUG: + subprocess.call("cygdb . --args python-dbg wxpython.py", shell=True) +else: + subprocess.call("python wxpython.py", shell=True) diff --git a/cefpython/cef1/linux/example.py b/cefpython/cef1/linux/example.py new file mode 100644 index 00000000..53d79a62 --- /dev/null +++ b/cefpython/cef1/linux/example.py @@ -0,0 +1,11 @@ +import os +import platform +import subprocess +import sys + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +os.chdir("./binaries_%s" % BITS) + +subprocess.call("python wxpython.py", shell=True) diff --git a/cefpython/cef1/linux/installer/README.txt.template b/cefpython/cef1/linux/installer/README.txt.template new file mode 100644 index 00000000..be6827b6 --- /dev/null +++ b/cefpython/cef1/linux/installer/README.txt.template @@ -0,0 +1,23 @@ +1. To install CEF Python 1 type: + + sudo python setup.py install + + This will install cefpython1 package to + /usr/local/lib/python2.7/dist-packages/ + +2. In the same directory that setup.py resides there is + an examples/ directory, run some example scripts from there: + + cd examples/ + python wxpython.py + python pygtk_.py + cd wx/ + python sample1.py + python sample2.py + python sample3.py + +Note: + Examples directory can also be found in package's directory: + /usr/local/lib/python2.7/dist-packages/cefpython1/examples/ + But to run examples from there you would have to chmod 0777 + the examples/ directory as it needs permission to create log files. diff --git a/cefpython/cef1/linux/installer/__init__.py.template b/cefpython/cef1/linux/installer/__init__.py.template new file mode 100644 index 00000000..ca81eea9 --- /dev/null +++ b/cefpython/cef1/linux/installer/__init__.py.template @@ -0,0 +1,12 @@ +import ctypes, os +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), "libcef.so") +ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + +import sys +if 0x02070000 <= sys.hexversion < 0x03000000: + from . import cefpython_py27 as cefpython +else: + raise Exception("Unsupported python version: " + sys.version) + +__version__ = "%(APP_VERSION)s" +__author__ = "The CEF Python authors" diff --git a/cefpython/cef1/linux/installer/make-setup.py b/cefpython/cef1/linux/installer/make-setup.py new file mode 100644 index 00000000..caddb875 --- /dev/null +++ b/cefpython/cef1/linux/installer/make-setup.py @@ -0,0 +1,119 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a setup package. + +import sys +import os +import platform +import argparse +import re +import platform +import shutil +import glob + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +PACKAGE_NAME = "cefpython1" + +README_TEMPLATE = os.getcwd()+r"/README.txt.template" +INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template" +SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template" + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + vars = {} + vars["APP_VERSION"] = args.version + + print("Reading template: %s" % README_TEMPLATE) + f = open(README_TEMPLATE) + README_CONTENT = f.read() % vars + f.close() + + print("Reading template: %s" % INIT_TEMPLATE) + f = open(INIT_TEMPLATE) + INIT_CONTENT = f.read() % vars + f.close() + + print("Reading template: %s" % SETUP_TEMPLATE) + f = open(SETUP_TEMPLATE) + SETUP_CONTENT = f.read() % vars + f.close() + + installer_dir = os.path.dirname(os.path.abspath(__file__)) + + setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]+"-linux-"+BITS+"-setup" + print("Creating setup dir: "+setup_dir) + os.mkdir(setup_dir) + + package_dir = setup_dir+"/"+PACKAGE_NAME + print("Creating package dir") + os.mkdir(package_dir) + + print("Creating README.txt from template") + with open(setup_dir+"/README.txt", "w") as f: + f.write(README_CONTENT) + + print("Creating setup.py from template") + with open(setup_dir+"/setup.py", "w") as f: + f.write(SETUP_CONTENT) + + binaries_dir = os.path.abspath(installer_dir+"/../binaries_"+BITS+"/") + print("Copying binaries to package dir") + ret = os.system("cp -rf "+binaries_dir+"/* "+package_dir) + assert ret == 0 + + os.chdir(package_dir) + print("Removing .log files from the package dir") + ret = os.system("rm *.log") + # assert ret == 0 - if there are no .log files this assert would fail. + os.chdir(installer_dir) + + print("Creating __init__.py from template") + with open(package_dir+"/__init__.py", "w") as f: + f.write(INIT_CONTENT) + + print("Creating examples dir in package dir") + os.mkdir(package_dir+"/examples/") + + print("Creating wx dir in package dir") + os.mkdir(package_dir+"/wx/") + + print("Moving example scripts from package dir to examples dir") + examples = glob.glob(package_dir+"/*.py") + for example in examples: + # Ignore: cefpython_py27.py - dummy API script + if os.path.basename(example).startswith("cefpython_"): + continue + # Ignore: __init__.py + if os.path.basename(example).startswith("__"): + continue + os.rename(example, package_dir+"/examples/"+os.path.basename(example)) + ret = os.system("mv "+package_dir+"/*.html "+package_dir+"/examples/") + assert ret == 0 + + print("Copying wx-subpackage to wx dir in package dir") + wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx-subpackage/") + ret = os.system("cp -rf "+wx_subpackage_dir+"/* "+package_dir+"/wx/") + assert ret == 0 + + print("Moving wx examples from wx/examples to examples/wx") + shutil.move(package_dir+"/wx/examples", package_dir+"/wx/wx/") + shutil.move(package_dir+"/wx/wx/", package_dir+"/examples/") + + print("Copying package dir examples to setup dir") + ret = os.system("cp -rf "+package_dir+"/examples/ "+setup_dir+"/examples/") + assert ret == 0 + + print("Setup Package created.") + +if __name__ == "__main__": + main() diff --git a/cefpython/cef1/linux/installer/setup.py.template b/cefpython/cef1/linux/installer/setup.py.template new file mode 100644 index 00000000..1a507843 --- /dev/null +++ b/cefpython/cef1/linux/installer/setup.py.template @@ -0,0 +1,26 @@ +from distutils.core import setup + +setup( + name='cefpython1', # No spaces here, so that it works with deb packages. + version='%(APP_VERSION)s', + description='Python bindings for the Chromium Embedded Framework', + license='BSD 3-Clause', + author='Czarek Tomczak', + author_email='czarek.tomczak@gmail.com', + url='http://code.google.com/p/cefpython/', + packages=['cefpython1', 'cefpython1.wx'], + package_data={'cefpython1': [ + 'examples/*.py', + 'examples/*.html', + 'examples/wx/*.py', + 'examples/wx/*.html', + 'examples/wx/*.png', + 'locales/*.pak', + 'wx/*.txt', + 'wx/images/*.png', + '*.txt', + 'cefclient', + '*.so', + '*.pak', + ]} +) diff --git a/cefpython/cef1/linux/setup/.gitignore b/cefpython/cef1/linux/setup/.gitignore new file mode 100644 index 00000000..0882aaec --- /dev/null +++ b/cefpython/cef1/linux/setup/.gitignore @@ -0,0 +1,5 @@ +build/ +cefpython.cpp +cython_debug/ +*.pyx +*.cpp \ No newline at end of file diff --git a/cefpython/cef1/linux/setup/cefpython.h b/cefpython/cef1/linux/setup/cefpython.h new file mode 100644 index 00000000..3555254b --- /dev/null +++ b/cefpython/cef1/linux/setup/cefpython.h @@ -0,0 +1,64 @@ +#ifndef __PYX_HAVE__cefpython_py27 +#define __PYX_HAVE__cefpython_py27 + + +#ifndef __PYX_HAVE_API__cefpython_py27 + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +__PYX_EXTERN_C DL_IMPORT(bool) CookieVisitor_Visit(int, CefCookie const &, int, int, bool &); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadEnd(CefRefPtr, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadStart(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LoadHandler_OnLoadError(CefRefPtr, CefRefPtr, enum cef_handler_errorcode_t, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnKeyEvent(CefRefPtr, enum cef_handler_keyevent_type_t, int, int, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnStateChange(int, CefRefPtr, enum cef_weburlrequest_state_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnRedirect(int, CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnHeadersReceived(int, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnProgress(int, CefRefPtr, uint64_t, uint64_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnData(int, CefRefPtr, void *, int); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnError(int, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) ContentFilterHandler_ProcessData(int, void const *, int, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(void) ContentFilterHandler_Drain(int, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeBrowse(CefRefPtr, CefRefPtr, CefRefPtr, enum cef_handler_navtype_t, bool); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeResourceLoad(CefRefPtr, CefRefPtr, CefString &, CefRefPtr &, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceRedirect(CefRefPtr, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceResponse(CefRefPtr, CefString &, CefRefPtr, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnProtocolExecution(CefRefPtr, CefString &, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetDownloadHandler(CefRefPtr, CefString const &, CefString const &, int64, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr, bool, CefString &, int, CefString &, CefString &, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetCookieManager(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr, CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnConsoleMessage(CefRefPtr, CefString &, CefString &, int); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnContentsSizeChange(CefRefPtr, CefRefPtr, int, int); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnNavStateChange(CefRefPtr, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnStatusMessage(CefRefPtr, CefString &, enum cef_handler_statustype_t); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnTooltip(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_DoClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnAfterCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_RunModal(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) DragHandler_OnDragStart(CefRefPtr, CefRefPtr, enum cef_drag_operations_mask_t); +__PYX_EXTERN_C DL_IMPORT(bool) DragHandler_OnDragEnter(CefRefPtr, CefRefPtr, enum cef_drag_operations_mask_t); +__PYX_EXTERN_C DL_IMPORT(bool) DownloadHandler_ReceivedData(int, void *, int); +__PYX_EXTERN_C DL_IMPORT(void) DownloadHandler_Complete(int); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnUncaughtException(CefRefPtr, CefRefPtr, CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) V8FunctionHandler_Execute(CefRefPtr, int, CefString &, CefRefPtr, CefV8ValueList &, CefRefPtr &, CefString &); + +#endif /* !__PYX_HAVE_API__cefpython_py27 */ + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcefpython_py27(void); +#else +PyMODINIT_FUNC PyInit_cefpython_py27(void); +#endif + +#endif /* !__PYX_HAVE__cefpython_py27 */ diff --git a/cefpython/cef1/linux/setup/fix_includes.py b/cefpython/cef1/linux/setup/fix_includes.py new file mode 100755 index 00000000..e25922ba --- /dev/null +++ b/cefpython/cef1/linux/setup/fix_includes.py @@ -0,0 +1,109 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# First, it copies all .pyx files from upper directory to setup/. +# Then, fixes repeating of "include" statements in pyx files. + +# Only the mainfile needs to have "include" statements, +# but we're using PyCharm and to get rid of "unresolved references" +# and other errors displayed in pycharm we are adding "include" +# statements in all of the pyx files. + +# I'm not 100% sure how includes work in Cython, but I suspect that +# a few includes of the same file will include the same content more +# than once, it should work, but function and variable definitions are +# duplicated, it is some kind of overhead and it could lead to some +# problems in the future, better to fix it now. + +# It also checks cdef & cpdef functions whether they are not missing "except *", +# it is required to add it when returning non-python type. + +import glob +import os +import re +import shutil +import sys + +def ExceptAllMissing(content): + + # This is not perfect, won't detect C++ custom types, but will find + # the built-in types, templates and pointers. + patterns = [] + patterns.append( + r"\bcp?def\s+" + "((int|short|long|double|char|unsigned|float|double|cpp_bool" + "|cpp_string|cpp_wstring|uint64_t|uintptr_t|void" + "|CefString)\s+)+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A template ends with bracket: CefRefPtr[CefBrowser] + # or a pointer ends with asterisk: CefBrowser* + "[^\s]+[\]*]\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A reference, eg. CefString& + "[^\s]+&\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + + for pattern in patterns: + match = re.search(pattern, content) + if match: break + + if match: + lineNumber = (content.count("\n", 0, match.start()) + 1) + return lineNumber + +print("\n") +mainfile = "cefpython.pyx" + +pyxfiles = glob.glob("../../../*.pyx") +if not len(pyxfiles): + sys.exit(1) +pyxfiles = [file for file in pyxfiles if file.find(mainfile) == -1] +# Now, pyxfiles contains all pyx files except the mainfile (cefpython.pyx), +# we do not fix includes in mainfile. + +# So that this is the right directory we're in. +if os.path.exists("setup"): + print("Wrong directory, we should be inside setup!") + sys.exit(1) + +# Remove old pyx files in setup directory. +oldpyxfiles = glob.glob("./*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +# Copying pyxfiles and reading its contents. + +print("Copying .pyx files to /setup/: %s" % pyxfiles) +shutil.copy("../../../%s" % mainfile, "./%s" % mainfile) +# Rest of the files will be copied in for loop below. + +print("Fixing includes in .pyx files:") +for pyxfile in pyxfiles: + newfile = "./%s" % os.path.basename(pyxfile) + shutil.copy(pyxfile, newfile) + pyxfile = newfile + with open(pyxfile, "r") as pyxfileopened: + content = pyxfileopened.read() + lineNumber = ExceptAllMissing(content) + if lineNumber: + print("WARNING: 'except *' missing in a cdef/cpdef function, " + "in file %s on line %d" % (os.path.basename(pyxfile), lineNumber)) + sys.exit(1) + # Do not remove the newline - so that line numbers are exact with originals. + (content, subs) = re.subn(r"^include[\t ]+[\"'][^\"'\n\r]+[\"'][\t ]*", "", content, flags=re.MULTILINE) + if subs: + print("%s includes removed in: %s" % (subs, os.path.basename(pyxfile))) + # Reading and writing with the same handle using "r+" mode doesn't work, + # you need to seek(0) and write the same amount of bytes that was in the + # file, otherwise old data from the end of file stays. + with open(pyxfile, "w") as pyxfileopened: + pyxfileopened.write(content) + +print("\n") diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper.a b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper.a new file mode 100644 index 00000000..9215a3c4 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper.a differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o new file mode 100644 index 00000000..f23f5c03 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o new file mode 100644 index 00000000..39a281dd Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o new file mode 100644 index 00000000..eb88875a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o new file mode 100644 index 00000000..42df3151 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o new file mode 100644 index 00000000..027306ee Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o new file mode 100644 index 00000000..aa96110d Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o new file mode 100644 index 00000000..f685787e Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o new file mode 100644 index 00000000..4125b976 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o new file mode 100644 index 00000000..55f3c45a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o new file mode 100644 index 00000000..e8930421 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o new file mode 100644 index 00000000..57db0a38 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o new file mode 100644 index 00000000..28e273e6 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o new file mode 100644 index 00000000..f87544dd Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o new file mode 100644 index 00000000..6cce1e2c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o new file mode 100644 index 00000000..563ca741 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o new file mode 100644 index 00000000..2c5810aa Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o new file mode 100644 index 00000000..2a10e041 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o new file mode 100644 index 00000000..98177d04 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o new file mode 100644 index 00000000..a6db93ae Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o new file mode 100644 index 00000000..c40302bb Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o new file mode 100644 index 00000000..19d57206 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o new file mode 100644 index 00000000..54eac7ee Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o new file mode 100644 index 00000000..50e66ff3 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o new file mode 100644 index 00000000..951a350c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o new file mode 100644 index 00000000..7ef9e7bf Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o new file mode 100644 index 00000000..41a200b8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o new file mode 100644 index 00000000..1e2ea86a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o new file mode 100644 index 00000000..0c4c12d5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o new file mode 100644 index 00000000..731cd0c3 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o new file mode 100644 index 00000000..68c73f30 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o new file mode 100644 index 00000000..9d55c274 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o new file mode 100644 index 00000000..17b1ad49 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o new file mode 100644 index 00000000..88e2c220 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o new file mode 100644 index 00000000..5b671d76 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o new file mode 100644 index 00000000..adc598a4 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o new file mode 100644 index 00000000..67d8a42c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o new file mode 100644 index 00000000..895e50d5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o new file mode 100644 index 00000000..397f7eb2 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o new file mode 100644 index 00000000..2f5214b9 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o new file mode 100644 index 00000000..60f93d34 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o new file mode 100644 index 00000000..9554aee5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o new file mode 100644 index 00000000..fd83cc3a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o new file mode 100644 index 00000000..8c2579f4 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o new file mode 100644 index 00000000..a25475da Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o new file mode 100644 index 00000000..2d719069 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o new file mode 100644 index 00000000..17665253 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o new file mode 100644 index 00000000..2cf20b82 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o new file mode 100644 index 00000000..810806d6 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o new file mode 100644 index 00000000..0e08c001 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o new file mode 100644 index 00000000..68feeebc Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o new file mode 100644 index 00000000..dae1d61e Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o new file mode 100644 index 00000000..ed08bc6f Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o new file mode 100644 index 00000000..3004475e Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o new file mode 100644 index 00000000..e7960b6f Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o new file mode 100644 index 00000000..3fb5e216 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o new file mode 100644 index 00000000..0991bc90 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o new file mode 100644 index 00000000..8ff62b6b Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o new file mode 100644 index 00000000..adee392c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o new file mode 100644 index 00000000..14e768ab Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o new file mode 100644 index 00000000..d9fdcfae Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/transfer_util.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/transfer_util.o new file mode 100644 index 00000000..530e235e Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/transfer_util.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o new file mode 100644 index 00000000..c3bc5c86 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o new file mode 100644 index 00000000..c448d225 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o new file mode 100644 index 00000000..fee858f2 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o new file mode 100644 index 00000000..89e6e329 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o differ diff --git a/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o new file mode 100644 index 00000000..7c251744 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_32bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper.a b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper.a new file mode 100644 index 00000000..5f4c70c7 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper.a differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o new file mode 100644 index 00000000..2cef598c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/app_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o new file mode 100644 index 00000000..70b2ba24 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/client_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o new file mode 100644 index 00000000..79ea6c8f Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/content_filter_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o new file mode 100644 index 00000000..4ca161db Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/cookie_visitor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o new file mode 100644 index 00000000..1ed4cf11 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/display_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o new file mode 100644 index 00000000..59afd7e0 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domevent_listener_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o new file mode 100644 index 00000000..ec64302d Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/domvisitor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o new file mode 100644 index 00000000..80fb7ee8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/download_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o new file mode 100644 index 00000000..ff271ebb Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/drag_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o new file mode 100644 index 00000000..75818b8e Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/find_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o new file mode 100644 index 00000000..715caf67 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/focus_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o new file mode 100644 index 00000000..f363eae4 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/geolocation_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o new file mode 100644 index 00000000..e97302f7 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/get_geolocation_callback_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o new file mode 100644 index 00000000..5299dfe5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/jsdialog_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o new file mode 100644 index 00000000..b3fed6b7 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/keyboard_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o new file mode 100644 index 00000000..14215e65 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/life_span_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o new file mode 100644 index 00000000..a10a89b4 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/load_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o new file mode 100644 index 00000000..bbe50bb6 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/menu_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o new file mode 100644 index 00000000..4be8b778 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/permission_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o new file mode 100644 index 00000000..6fe4eab9 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/print_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o new file mode 100644 index 00000000..04fbacb8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/proxy_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o new file mode 100644 index 00000000..d2ca1dc2 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/read_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o new file mode 100644 index 00000000..102b83a1 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/render_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o new file mode 100644 index 00000000..d68a5ea6 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/request_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o new file mode 100644 index 00000000..6d6f1d23 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/resource_bundle_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o new file mode 100644 index 00000000..d3158cca Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o new file mode 100644 index 00000000..f949ac5b Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/scheme_handler_factory_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o new file mode 100644 index 00000000..774e8c6a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/task_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o new file mode 100644 index 00000000..7850b4da Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8accessor_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o new file mode 100644 index 00000000..72cd1ca5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8context_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o new file mode 100644 index 00000000..5ed250bf Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/v8handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o new file mode 100644 index 00000000..649c1f30 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/web_urlrequest_client_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o new file mode 100644 index 00000000..6ea8c434 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/write_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o new file mode 100644 index 00000000..0857f6d8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/cpptoc/zoom_handler_cpptoc.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o new file mode 100644 index 00000000..04ff974b Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/browser_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o new file mode 100644 index 00000000..25e0a0d8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/command_line_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o new file mode 100644 index 00000000..81af9b0c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/cookie_manager_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o new file mode 100644 index 00000000..e65a077b Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domdocument_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o new file mode 100644 index 00000000..88a8820f Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domevent_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o new file mode 100644 index 00000000..32baac18 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/domnode_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o new file mode 100644 index 00000000..aec8c72d Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/drag_data_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o new file mode 100644 index 00000000..0df54b94 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/frame_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o new file mode 100644 index 00000000..37f483d3 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/geolocation_callback_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o new file mode 100644 index 00000000..c6956dd5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o new file mode 100644 index 00000000..ef5e6ec2 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/post_data_element_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o new file mode 100644 index 00000000..cc2de3ca Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/request_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o new file mode 100644 index 00000000..4f3ba3bf Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/response_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o new file mode 100644 index 00000000..2b875351 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_handler_callback_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o new file mode 100644 index 00000000..ec91c3d7 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/scheme_registrar_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o new file mode 100644 index 00000000..835a91fd Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o new file mode 100644 index 00000000..ea834a16 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/stream_writer_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o new file mode 100644 index 00000000..4f375ef5 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8context_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o new file mode 100644 index 00000000..46e2790a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8exception_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o new file mode 100644 index 00000000..63fbc566 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_frame_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o new file mode 100644 index 00000000..8d3d761b Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8stack_trace_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o new file mode 100644 index 00000000..0229ba7f Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/v8value_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o new file mode 100644 index 00000000..ba5665ac Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_plugin_info_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o new file mode 100644 index 00000000..ea9eeba3 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/web_urlrequest_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o new file mode 100644 index 00000000..cb1464c3 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/xml_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o new file mode 100644 index 00000000..c87fa499 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/ctocpp/zip_reader_ctocpp.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/transfer_util.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/transfer_util.o new file mode 100644 index 00000000..8a99b83a Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/transfer_util.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o new file mode 100644 index 00000000..c2c0a048 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_byte_read_handler.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o new file mode 100644 index 00000000..4cdf98e8 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_xml_object.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o new file mode 100644 index 00000000..13ac236c Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/cef_zip_archive.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o new file mode 100644 index 00000000..d5ff4776 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper.o differ diff --git a/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o new file mode 100644 index 00000000..5c3e9671 Binary files /dev/null and b/cefpython/cef1/linux/setup/lib_64bit/libcef_dll_wrapper/libcef_dll/wrapper/libcef_dll_wrapper2.o differ diff --git a/cefpython/cef1/linux/setup/setup.py b/cefpython/cef1/linux/setup/setup.py new file mode 100755 index 00000000..7efd4b03 --- /dev/null +++ b/cefpython/cef1/linux/setup/setup.py @@ -0,0 +1,105 @@ +from distutils.core import setup +# Use "Extension" from Cython.Distutils so that "cython_directives" works. +# from distutils.extension import Extension +from Cython.Distutils import build_ext, Extension +import sys +import platform +from Cython.Compiler import Options + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +# Stop on first error, otherwise hundreds of errors appear in the console. +Options.fast_fail = True + +# Written to cython_includes/compile_time_constants.pxi +CEF_VERSION = 1 + +# Python version string: "27" or "32". +PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor) + +def CompileTimeConstants(): + + print("Generating: cython_includes/compile_time_constants.pxi") + with open("./../../../cython_includes/compile_time_constants.pxi", "w") as fd: + fd.write('# This file was generated by setup.py\n') + # A way around Python 3.2 bug: UNAME_SYSNAME is not set. + fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0]) + fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION) + fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major) + +CompileTimeConstants() + +ext_modules = [Extension( + + "cefpython_py%s" % PYTHON_VERSION, + ["cefpython.pyx"], + + # Ignore the warning in the console: + # > C:\Python27\lib\distutils\extension.py:133: UserWarning: + # > Unknown Extension options: 'cython_directives' warnings.warn(msg) + cython_directives={ + # Any conversion to unicode must be explicit using .decode(). + "c_string_type": "bytes", + "c_string_encoding": "utf-8", + }, + + language='c++', + include_dirs=[ + r'./../', + r'./../../', + r'./../../../', + r'./../../../cython_includes/', + '/usr/include/gtk-2.0', + '/usr/include/glib-2.0', + '/usr/lib/i386-linux-gnu/gtk-2.0/include', + '/usr/lib/i386-linux-gnu/glib-2.0/include', + '/usr/include/cairo', + '/usr/include/pango-1.0', + '/usr/include/gdk-pixbuf-2.0', + '/usr/include/atk-1.0', + # 64bit Ubuntu + '/usr/lib/x86_64-linux-gnu/glib-2.0/include', + '/usr/lib/x86_64-linux-gnu/gtk-2.0/include', + ], + + # http_authentication not implemented on Linux. + library_dirs=[ + r'./lib_%s' % BITS, + r'./../../v8function_handler/', + r'./../../client_handler/', + r'./../../../cpp_utils/' + ], + + libraries=[ + 'cef_dll_wrapper', + 'v8function_handler', + 'client_handler', + 'cpp_utils' + ], + + # Loading libcef.so will only work when running scripts from the same + # directory that libcef.so resides in when you put "./" in here. + # runtime_library_dirs=[ + # './' + #], + + # /EHsc - using STL string, multimap and others that use C++ exceptions. + extra_compile_args=[], + + # '/ignore:4217' - silence warnings: "locally defined symbol _V8FunctionHandler_Execute + # imported in function "public: virtual bool __thiscall V8FunctionHandler::Execute". + # client_handler or other vcprojects include setup/cefpython.h, + # this is a list of functions with "public" statement that is + # accessible from c++. + extra_link_args=[], + + # Defining macros: + # define_macros = [("UNICODE","1"), ("_UNICODE","1"), ] +)] + +setup( + name = 'cefpython_py%s' % PYTHON_VERSION, + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules +) diff --git a/cefpython/cef1/util.h b/cefpython/cef1/util.h new file mode 100644 index 00000000..ba0305c1 --- /dev/null +++ b/cefpython/cef1/util.h @@ -0,0 +1,37 @@ +// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEF_TESTS_CEFCLIENT_UTIL_H_ +#define CEF_TESTS_CEFCLIENT_UTIL_H_ +#pragma once + +#include "include/cef_task.h" + +#if defined(OS_WIN) + +#include // NOLINT(build/include_order) + +#ifndef NDEBUG +#define ASSERT(condition) if (!(condition)) { DebugBreak(); } +#else +#define ASSERT(condition) ((void)0) +#endif + +#else // !OS_WIN + +#include // NOLINT(build/include_order) + +#ifndef NDEBUG +#define ASSERT(condition) if (!(condition)) { assert(false); } +#else +#define ASSERT(condition) ((void)0) +#endif + +#endif // !OS_WIN + +#define REQUIRE_UI_THREAD() ASSERT(CefCurrentlyOn(TID_UI)); +#define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO)); +#define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE)); + +#endif // CEF_TESTS_CEFCLIENT_UTIL_H_ diff --git a/cefpython/cef1/v8function_handler/.gitignore b/cefpython/cef1/v8function_handler/.gitignore new file mode 100644 index 00000000..151a620f --- /dev/null +++ b/cefpython/cef1/v8function_handler/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a \ No newline at end of file diff --git a/cefpython/cef1/v8function_handler/Makefile b/cefpython/cef1/v8function_handler/Makefile new file mode 100644 index 00000000..c8d094d4 --- /dev/null +++ b/cefpython/cef1/v8function_handler/Makefile @@ -0,0 +1,20 @@ +# -g - extra debug information +# -O1 - more precise backtraces +# -fPIC - required when using -shared option +# -Wall - show important warnings +# -Werror - treat warnings as errors + +CC = g++ +CCFLAGS = -g + +SRC = v8function_handler.cpp +OBJ = $(SRC:.cpp=.o) +OUT = libv8function_handler.a + +INC = -I./../ -I/usr/include/python2.7 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include + +.cpp.o: + $(CC) -fPIC $(INC) $(CCFLAGS) -c $< -o $@ + +$(OUT): $(OBJ) + ar rcs $(OUT) $(OBJ) diff --git a/cefpython/cef1/v8function_handler/v8function_handler.cpp b/cefpython/cef1/v8function_handler/v8function_handler.cpp new file mode 100644 index 00000000..e05a558b --- /dev/null +++ b/cefpython/cef1/v8function_handler/v8function_handler.cpp @@ -0,0 +1,15 @@ +#include "v8function_handler.h" + +// Implementation cannot be in .h as it is included by cython's setup script and +// V8FunctionHandler_Execute() is not visible at that time. +bool V8FunctionHandler::Execute( + const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) +{ + // The methods of this class will always be called on the UI thread, no need to call REQUIRE_UI_THREAD(). + return V8FunctionHandler_Execute(this->GetContext(), this->pythonCallbackID, + const_cast(name), object, const_cast(arguments), retval, exception); +} diff --git a/cefpython/cef1/v8function_handler/v8function_handler.h b/cefpython/cef1/v8function_handler/v8function_handler.h new file mode 100644 index 00000000..cc33980e --- /dev/null +++ b/cefpython/cef1/v8function_handler/v8function_handler.h @@ -0,0 +1,66 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +typedef void (*RemovePythonCallback_type)( + int callbackID +); + +class V8FunctionHandler : public CefV8Handler +{ +public: + V8FunctionHandler() + { + this->removePythonCallback = NULL; + this->pythonCallbackID = 0; + } + virtual ~V8FunctionHandler() + { + if (this->removePythonCallback) { + this->removePythonCallback(this->pythonCallbackID); + } + } + + CefRefPtr __context; + + void SetContext(CefRefPtr context) + { + this->__context = context; + } + CefRefPtr GetContext() + { + return this->__context; + } + + + // CefV8Handler methods. + + RemovePythonCallback_type removePythonCallback; + int pythonCallbackID; + + void SetCallback_RemovePythonCallback(RemovePythonCallback_type callback) + { + this->removePythonCallback = callback; + } + void SetPythonCallbackID(int callbackID) + { + this->pythonCallbackID = callbackID; + } + virtual bool Execute( + const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE; + +protected: + IMPLEMENT_REFCOUNTING(V8FunctionHandler); +}; diff --git a/cefpython/cef1/v8function_handler/v8function_handler.sln b/cefpython/cef1/v8function_handler/v8function_handler.sln new file mode 100644 index 00000000..5929d6fc --- /dev/null +++ b/cefpython/cef1/v8function_handler/v8function_handler.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8function_handler_py27", "v8function_handler_py27.vcproj", "{6CA41D5D-3546-4363-B670-97FFE4B88D4C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8function_handler_py32", "v8function_handler_py32.vcproj", "{9E47F572-3024-4C6E-80E5-4C4BF79EEE8E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6CA41D5D-3546-4363-B670-97FFE4B88D4C}.Debug|Win32.ActiveCfg = Debug|Win32 + {6CA41D5D-3546-4363-B670-97FFE4B88D4C}.Debug|Win32.Build.0 = Debug|Win32 + {6CA41D5D-3546-4363-B670-97FFE4B88D4C}.Release|Win32.ActiveCfg = Release|Win32 + {6CA41D5D-3546-4363-B670-97FFE4B88D4C}.Release|Win32.Build.0 = Release|Win32 + {9E47F572-3024-4C6E-80E5-4C4BF79EEE8E}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E47F572-3024-4C6E-80E5-4C4BF79EEE8E}.Release|Win32.ActiveCfg = Release|Win32 + {9E47F572-3024-4C6E-80E5-4C4BF79EEE8E}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cefpython/cef1/v8function_handler/v8function_handler_py27.vcproj b/cefpython/cef1/v8function_handler/v8function_handler_py27.vcproj new file mode 100644 index 00000000..2e071239 --- /dev/null +++ b/cefpython/cef1/v8function_handler/v8function_handler_py27.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/v8function_handler/v8function_handler_py32.vcproj b/cefpython/cef1/v8function_handler/v8function_handler_py32.vcproj new file mode 100644 index 00000000..71efefba --- /dev/null +++ b/cefpython/cef1/v8function_handler/v8function_handler_py32.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/windows/.gitignore b/cefpython/cef1/windows/.gitignore new file mode 100644 index 00000000..f1e2fe98 --- /dev/null +++ b/cefpython/cef1/windows/.gitignore @@ -0,0 +1,10 @@ +# Ignore binary files and static libraries, they can +# be build using the build instructions on the wiki page: +# https://code.google.com/p/cefpython/wiki/BuildOnWindows + +*.pak +*.exe +*.dll + +*.lib +*.pyd diff --git a/cefpython/cef1/windows/binaries/LICENSE.txt b/cefpython/cef1/windows/binaries/LICENSE.txt new file mode 100644 index 00000000..97f1e961 --- /dev/null +++ b/cefpython/cef1/windows/binaries/LICENSE.txt @@ -0,0 +1,36 @@ +Copyright (c) 2012-2013 Czarek Tomczak. Portions Copyright +(c) 2008-2013 Marshall A.Greenblatt, 2006-2009 Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef1/windows/binaries/Microsoft.VC90.CRT.manifest b/cefpython/cef1/windows/binaries/Microsoft.VC90.CRT.manifest new file mode 100644 index 00000000..338438df --- /dev/null +++ b/cefpython/cef1/windows/binaries/Microsoft.VC90.CRT.manifest @@ -0,0 +1,6 @@ + + + + + KSaO8M0iCtPF6YEr79P1dZsnomY= ojDmTgpYMFRKJYkPcM6ckpYkWUU= tVogb8kezDre2mXShlIqpp8ErIg= + \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/README.txt b/cefpython/cef1/windows/binaries/README.txt new file mode 100644 index 00000000..b8f84acc --- /dev/null +++ b/cefpython/cef1/windows/binaries/README.txt @@ -0,0 +1,112 @@ +Chromium Embedded Framework (CEF) Standard Binary Distribution for Windows +------------------------------------------------------------------------------- + +Date: June 06, 2013 + +CEF Version: 1.1453.1273 +CEF URL: http://chromiumembedded.googlecode.com/svn/branches/1453/cef1@1273 + +Chromium Verison: 27.0.1453.110 +Chromium URL: http://src.chromium.org/svn/branches/1453/src@202711 + +This distribution contains all components necessary to build and distribute an +application using CEF on the Windows platform. Please see the LICENSING +section of this document for licensing terms and conditions. + +CONTENTS +-------- + +cefclient Contains the cefclient sample application configured to build + using the files in this distribution. + +Debug Contains libcef.dll, libcef.lib and other components required to + build and run the debug version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +include Contains all required CEF header files. + +libcef_dll Contains the source code for the libcef_dll_wrapper static library + that all applications using the CEF C++ API must link against. + +Release Contains libcef.dll, libcef.lib and other components required to + build and run the release version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +Resources Contains resources required by libcef.dll. By default these files + should be placed in the same directory as libcef.dll. By default + these files should be placed in the same directory as libcef.dll + and will be copied there as part of the build process. + + +USAGE +----- + +Visual Studio 2012 and Visual Studio 2010: + Open the cefclient2010.sln solution in Visual Studio and build. + +Visual Studio 2008: + Open the cefclient2008.sln solution in Visual Studio and build. + +Visual Studio 2005: + 1. Open the cefclient.vcproj and libcef_dll_wrapper.vcproj files in a text + editor. Change Version="9.00" to Version="8.00". + 2. Open the cefclient2005.sln file in a text editor. Change "Version 9.00" to + "Version 8.00". + 3. Open the cefclient2005.sln solution in Visual Studio and build. + +Please visit the CEF Website for additional usage information. + +http://code.google.com/p/chromiumembedded + +REDISTRIBUTION +-------------- + +This binary distribution contains the below components. Components listed under +the "required" section must be redistributed with all applications using CEF. +Components listed under the "optional" section may be excluded if the related +features will not be used. + +Required components: + +* CEF core library + libcef.dll + +* Unicode support + icudt.dll + +Optional components: + +* Localized resources + locales/ + Note: Contains localized strings for WebKit UI controls. A .pak file is loaded + from this folder based on the CefSettings.locale value. Only configured + locales need to be distributed. If no locale is configured the default locale + of "en-US" will be used. Locale file loading can be disabled completely using + CefSettings.pack_loading_disabled. The locales folder path can be customized + using CefSettings.locales_dir_path. + +* Other resources + devtools_resources.pak + Note: Contains WebKit image and inspector resources. Pack file loading can be + disabled completely using CefSettings.pack_loading_disabled. The resources + directory path can be customized using CefSettings.resources_dir_path. + +* Angle and Direct3D support + d3dcompiler_43.dll + d3dx9_43.dll + libEGL.dll + libGLESv2.dll + Note: Without these components the default ANGLE_IN_PROCESS graphics + implementation for HTML5 accelerated content like 2D canvas, 3D CSS and + WebGL will not function. To use the desktop GL graphics implementation which + does not require these components (and does not work on all systems) set + CefSettings.graphics_implementation to DESKTOP_IN_PROCESS. + +LICENSING +--------- + +The CEF project is BSD licensed. Please read the LICENSE.txt file included with +this binary distribution for licensing terms and conditions. Other software +included in this distribution is provided under other licenses. \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/cefadvanced.html b/cefpython/cef1/windows/binaries/cefadvanced.html new file mode 100644 index 00000000..9f0805e2 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefadvanced.html @@ -0,0 +1,306 @@ + + + + + CefAdvanced + + + + +Welcome to CEF Python - bindings for the Chromium Embedded Framework. +

+ +Project website: +http://code.google.com/p/cefpython/
+ +Wiki documentation: +http://code.google.com/p/cefpython/wiki/
+ +Support forum: +https://groups.google.com/group/cefpython?hl=en
+ +

User agent

+ + + +

Python version

+ + + +

Keyboard and mouse shortcuts

+ +
    +
  • Press F5 to refresh & rebind python<>javascript bindings + (does not work for the main module). +
  • Press F11 to go fullscreen, press F11 again to exit fullscreen. +
  • Press F12 key to show developer tools for the main frame. +
  • Press backspace to go Back in history. +
  • Use right mouse button context menu to go Back/Forward or to view the sources. +
  • Press Ctrl(+) to zoom in, Ctrl(-) to zoom out. +
+ +

Browse google

+ + http://www.google.com/ + +

Transparent window

+ + + python.TransparentPopup() + +

Browser object

+ + CanGoBack()
+ CanGoForward()
+ ClearHistory()
+ CloseBrowser()
+ CloseDevTools()
+ Find(searchId=0, searchText='test', forward=true, matchCase=false, findNext=false)
+ GetUserData('some')
+ GetFocusedFrame() + - throws an error, returning a PyFrame object to to javascript is not yet supported
+ GetFrame('simple') - throws an error, returning a PyFrame object to javascript is not yet supported
+ GetFrameNames()
+ GetMainFrame() + - throws an error, returning a PyFrame object to javascript is not yet supported
+ + GetOpenerWindowHandle()
+ + GetOuterWindowHandle()
+ GetWindowHandle()
+ GetZoomLevel()
+ GoBack()
+ GoForward()
+ HasDocument()
+ HidePopup()
+ IsFullscreen()
+ IsPopup()
+ IsPopupVisible()
+ + IsWindowRenderingDisabled()
+ Reload()
+ ReloadIgnoreCache()
+ SetFocus(false) + - inner window loses focus, check keyboard and mouse wheel scrolling
+ + SetUserData('some', 'something') - call GetUserData('some')
+ SetZoomLevel(2)
+ ShowDevTools()
+ StopLoad()
+ StopFinding(true) - call Find(), then StopFinding()
+ ToggleFullscreen()
+ +

Frame object

+ + Copy()
+ Cut()
+ Delete()
+ + ExecuteJavascript('alert(1)')
+ GetIdentifier()
+ + GetName()
+ GetProperty('name')
+ GetSource()
+ GetText()
+ GetUrl()
+ IsFocused()
+ IsMain()
+ LoadString('some html source', 'cef://some')
+ + LoadUrl('http://www.google.com/')
+ Paste()
+ Print()
+ Redo()
+ SelectAll()
+ + SetProperty('name', 'noname') - call GetProperty('name')
+ Undo()
+ ViewSource()
+ +

Browser view as an image

+ + Browser.GetImage() returns a PaintBuffer object that has the GetString() + method that returns the buffer as a string, that string can be + passed to PIL.Image.fromstring() and saved as a PNG or other + format. This test requires the PIL or pygame library to be installed:
+ + python.SaveImage('!cefadvanced.png', 'PNG')
+ + TODO: capture image of all the scrollable content on a webpage, + detect the height of the content in javascript and call + Browser.SetSize() using that height. + +

Test unicode string

+ + + python.GetUnicodeString()
+ You should see a long dash in python 2.7. + +

Test creation of second browser

+ + python.CreateSecondBrowser() + +

Test int32, uint, long

+ + python.GetType(2147483647)
+ python.GetType(2147483648) - here we get UINT from CEF so it is converted to long in Py2, int in Py3.
+ python.GetType(4294967295) - uint limit.
+ python.GetType(4294967296) - outside of uint limit, converted to float.
+ python.GetType(-2147483647)
+ python.GetType(-2147483648)
+ python.GetType(-2147483649) - here you get a FLOAT value, not long.
+
+ TODO: do these tests the other way, from javascript to python. + +
+ +

Basic authentication

+ + + + +
+ +

Frame.ExecuteJavascript()

+ +
+ python.ExecuteJavascript(jscode.value) - execute javascript from the textarea above. + +

Frames

+ + + + +

Javascript bindings

+ + See output in the console for the javascript bindings tests.
+ Note: "window." is optional, you can just call "python.Test1()".
+ +

Passing arguments

+ + python.Test1(100)
+ python.Test2(100, 'This string was passed from javascript [unicode: ąś]', '') - python.Test2() should return: [1,2, [2.1, {'3': 3, '4': [5,6]}], unicode...] +

+ + + python.Test1(array) (var array = [1]; array[100] = 100.01;) - the gap is filled with None values.
+ + + python.Test1(object) (var object = {a: 1, '3': 33};)
+ +
+ + python.Test1(nested) (var nested = [1,2, [3, 4, [5,6, [{7:7, 8: [9,10]}, 11]]]];) - dictionary keys will be in a different order in Python.
+ +
+ window.PyConfig = + +
+ Now change PyConfig: window.PyConfig={'option1': False, 'option2': 40}
+ Call __browser.GetMainFrame().GetProperty("PyConfig"): python.PrintPyConfig()
+ Try setting PyConfig during runtime using __browser.GetMainFrame().SetProperty(): python.ChangePyConfig() (then call python.PrintPyConfig()) + +

Javasript callbacks

+ + + + + python.TestJavascriptCallback(MyJSCallback)
+ MyJSCallback alerts arguments. + +

Python callbacks

+ +

See the output in the console.

+ + + + python.TestPythonCallbackThroughReturn()('some')
+ python.TestPythonCallbackThroughJavascriptCallback(JSCallbackForPythonCallback) + +

Errors

+ +

Typically when you browse a webpage javascript errors appear in + the developer tools javascript console (in cefadvanced.py there + is a binding to F12 key for the developer tools popup).

+ +

Global exception handler

+ + + +

You can catch javascript errors programmatically by + using JavascriptContextHandler.OnUncaughtException() callback, + to see the complete stack trace you need to set the + "uncaught_exception_stack_size" ApplicationSettings option to + a value greater than 0, test it:
+ + DoSomeError() +

+ +

Test error when calling javascript callback from python

+ + + + python.TestJavascriptCallback(JsCallbackThrowingError)
+ JsCallbackThrowingError throws new Error(). + +

Infinite recursion

+ + python.Test1(window)
+ You should see a python exception in the console (also in error.log), + as data structures can have maximum 8 levels of nesting. + +

Moving and resizing window

+ + python.ResizeWindow() - cefwindow.MoveWindow(__browser.GetWindowID(), width=500, height=500)
+ python.MoveWindow() - cefwindow.MoveWindow(__browser.GetWindowID(), xpos=0, ypos=0) + +

Popups

+ + window.open('cefsimple.html')
+ window.open('cefadvanced.html') + +

Overwriting window.alert()

+ +
def Alert(self, msg):
+        print "python.Alert() called instead of window.alert()"
+        win32gui.MessageBox(__browser.GetWindowID(), msg, "python.Alert()")
+ + window.alert('SOME ALERT!') +

+
def ChangeAlertDuringRuntime(self):
+        __browser.GetMainFrame().SetProperty("alert", self.Alert2)
+ python.ChangeAlertDuringRuntime() - now check window.alert() above, the messagebox style should be changed. + +

Find text on this page

+ +
def Find(self, searchText, findNext=False):
+        __browser.Find(1, searchText, forward=True, matchCase=False, findNext=findNext)
+ + + + + diff --git a/cefpython/cef1/windows/binaries/cefadvanced.py b/cefpython/cef1/windows/binaries/cefadvanced.py new file mode 100644 index 00000000..b7d3de05 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefadvanced.py @@ -0,0 +1,505 @@ +# coding=utf-8 + +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Checking whether python architecture and version are valid, +# otherwise an obfuscated error will be thrown when trying +# to load cefpython.pyd with a message "DLL load failed". + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import cefwindow + +# pywin32 extension +import win32api +import win32con +import win32gui + +import re +import imp +import inspect +import pprint +import time +import imp + +DEBUG = True + +# TODO: example of creating popup windows from python, +# call WindowInfo.SetAsPopup(). +# TODO: example of creating modal windows from python. + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +def InitDebugging(): + # Whether to print & log debug messages + if DEBUG: + cefpython.g_debug = True + cefpython.g_debugFile = GetApplicationPath("debug.log") + cefwindow.g_debug = True + +def CefAdvanced(): + sys.excepthook = ExceptHook + InitDebugging() + + appSettings = dict() + appSettings["log_file"] = GetApplicationPath("debug.log") + + # LOGSEVERITY_INFO - less debug oput. + # LOGSEVERITY_DISABLE - will not create "debug.log" file. + appSettings["log_severity"] = cefpython.LOGSEVERITY_VERBOSE + + # Enable only when debugging, otherwise performance might hurt. + appSettings["release_dcheck_enabled"] = True + + # Must be set so that OnUncaughtException() is called. + appSettings["uncaught_exception_stack_size"] = 100 + + cefpython.Initialize(applicationSettings=appSettings) + + # Closing main window quits the application as we define + # WM_DESTOROY message. + wndproc = { + win32con.WM_CLOSE: CloseWindow, + win32con.WM_DESTROY: QuitApplication, + win32con.WM_SIZE: cefpython.WindowUtils.OnSize, + win32con.WM_SETFOCUS: cefpython.WindowUtils.OnSetFocus, + win32con.WM_ERASEBKGND: cefpython.WindowUtils.OnEraseBackground + } + + windowHandle = cefwindow.CreateWindow( + title="CefAdvanced", className="cefadvanced", + width=900, height=710, icon="icon.ico", windowProc=wndproc) + + browserSettings = dict() + browserSettings["history_disabled"] = False + browserSettings["universal_access_from_file_urls_allowed"] = True + browserSettings["file_access_from_file_urls_allowed"] = True + + javascriptBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowHandle) + browser = cefpython.CreateBrowserSync( + windowInfo, browserSettings=browserSettings, + navigateUrl=GetApplicationPath("cefadvanced.html")) + browser.SetUserData("outerWindowHandle", windowInfo.parentWindowHandle) + browser.SetClientHandler(ClientHandler()) + browser.SetJavascriptBindings(javascriptBindings) + + javascriptRebindings = JavascriptRebindings(javascriptBindings, browser) + javascriptRebindings.Bind() + browser.SetUserData("javascriptRebindings", javascriptRebindings) + + cefpython.MessageLoop() + cefpython.Shutdown() + +def CloseWindow(windowHandle, msg, wparam, lparam): + browser = cefpython.GetBrowserByWindowHandle(windowHandle) + browser.CloseBrowser() + return win32gui.DefWindowProc(windowHandle, msg, wparam, lparam) + +def QuitApplication(windowHandle, msg, wparam, lparam): + win32gui.PostQuitMessage(0) + return 0 + +class JavascriptRebindings: + javascriptBindings = None + browser = None + + def __init__(self, javascriptBindings, browser): + self.javascriptBindings = javascriptBindings + self.browser = browser + + def Bind(self): + # These bindings are rebinded when pressing F5. + # It's not useful for the main module as it can't be reloaded. + python = Python() + python.browser = self.browser + + # Overwrite "window.alert". + # self.javascriptBindings.SetFunction("alert", python.Alert) + + self.javascriptBindings.SetObject("python", python) + self.javascriptBindings.SetObject("browser", self.browser) + self.javascriptBindings.SetObject("frame", self.browser.GetMainFrame()) + self.javascriptBindings.SetProperty("PyConfig", + {"option1": True, "option2": 20}) + + def Rebind(self): + # Reload all application modules, next rebind javascript bindings. + # Called from: OnKeyEvent > F5. + + currentDir = GetApplicationPath() + + for mod in sys.modules.values(): + if mod and mod.__name__ != "__main__": + # This module resides in app's directory. + if hasattr(mod, "__file__") and ( + mod.__file__.find(currentDir) != -1): + try: + imp.reload(mod) + if DEBUG: + print("Reloaded module: %s" % mod.__name__) + except (Exception, exc): + print("WARNING: reloading module failed: %s. " + "Exception: %s" % (mod.__name__, exc)) + + # cefpython & cefwindow modules have been reloaded, + # we need to re-initialize debugging. + InitDebugging() + + self.Bind() + self.javascriptBindings.Rebind() + +class ClientHandler: + + def OnLoadStart(self, browser, frame): + # print("OnLoadStart(): frame url: %s" % frame.GetUrl()) + pass + + def OnLoadEnd(self, browser, frame, httpStatusCode): + # print("OnLoadEnd(): frame url: %s" % frame.GetUrl()) + pass + + def OnLoadError(self, browser, frame, errorCode, failedUrl, errorText): + # print("OnLoadError() failedUrl: %s" % (failedUrl)) + errorText[0] = ("Custom error message when loading url fails, " + "see: def OnLoadError()") + return True + + def OnKeyEvent(self, browser, eventType, keyCode, modifiers, isSystemKey, + isAfterJavascript): + + # print("eventType = %s, keyCode=%s, modifiers=%s, isSystemKey=%s" % + # (eventType, keyCode, modifiers, isSystemKey)) + + if eventType != cefpython.KEYEVENT_RAWKEYDOWN or isSystemKey: + return False + + # Bind F12 to developer tools. + if keyCode == cefpython.VK_F12 and ( + cefpython.IsKeyModifier(cefpython.KEY_NONE, modifiers)): + browser.ShowDevTools() + return True + + # Bind F5 to refresh browser window. + # Also reload all modules and rebind javascript bindings. + if keyCode == cefpython.VK_F5 and ( + cefpython.IsKeyModifier(cefpython.KEY_NONE, modifiers)): + # When we press F5 in Developer Tools popup, there are + # no bindings in this window, error would be thrown. + # Pressing F5 in Developer Tools seem to not refresh + # the parent window. + if browser.GetUserData("javascriptRebindings"): + browser.GetUserData("javascriptRebindings").Rebind() + # This is not required, rebinding will work without refreshing page. + browser.ReloadIgnoreCache() + return True + + # Bind Ctrl(+) to increase zoom level + if keyCode in (187, 107) and ( + cefpython.IsKeyModifier(cefpython.KEY_CTRL, modifiers)): + browser.SetZoomLevel(browser.GetZoomLevel() +1) + return True + + # Bind Ctrl(-) to reduce zoom level + if keyCode in (189, 109) and ( + cefpython.IsKeyModifier(cefpython.KEY_CTRL, modifiers)): + browser.SetZoomLevel(browser.GetZoomLevel() -1) + return True + + # Bind F11 to go fullscreen. + if keyCode == cefpython.VK_F11 and ( + cefpython.IsKeyModifier(cefpython.KEY_NONE, modifiers)): + browser.ToggleFullscreen() + return True + + return False + + def OnConsoleMessage(self, browser, message, source, line): + appdir = GetApplicationPath().replace("\\", "/") + if appdir[1] == ":": + appdir = appdir[0].upper() + appdir[1:] + source = source.replace("file:///", "") + source = source.replace(appdir, "") + print("Console message: %s (%s:%s)\n" % (message, source, line)); + return False + + def OnResourceResponse(self, browser, url, response, filter): + # This function does not get called for local disk sources (file:///). + pass + # print("Resource: %s (status=%s)" % (url, response.GetStatus())) + # response.SetHeaderMap( + # {"Content-Length": 123, "Content-Type": "none"}) + # print("response.GetHeaderMap(): %s" % response.GetHeaderMap()) + # print("response.GetHeaderMultimap(): %s" % ( + # response.GetHeaderMultimap())) + + def OnUncaughtException(self, browser, frame, exception, stackTrace): + if not "cefadvanced.html" in frame.GetUrl(): + # Exit application when javascript encountered + # only for the cefadvanced.html example. + return + url = exception["scriptResourceName"] + stackTrace = cefpython.FormatJavascriptStackTrace(stackTrace) + if re.match(r"file:/+", url): + # Get a relative path of the html/js file, + # get rid of the "file://d:/.../cefpython/". + url = re.sub(r"^file:/+", "", url) + url = re.sub(r"[/\\]+", re.escape(os.sep), url) + url = re.sub(r"%s" % re.escape(GetApplicationPath()), + "", url, flags=re.IGNORECASE) + url = re.sub(r"^%s" % re.escape(os.sep), "", url) + raise Exception("%s.\n" + "On line %s in %s.\n" + "Source of that line: %s\nStack trace:\n%s" % ( + exception["message"], exception["lineNumber"], + url, exception["sourceLine"], stackTrace)) + + def OnTitleChange(self, browser, title): + # cefpython.WindowUtils.SetTitle(browser, "ąś") + # return False + return True + +def ModuleExists(module): + try: + imp.find_module(module) + return True + except ImportError: + return False + +class Python: + browser = None + + def SaveImage(self, outfile, format): + outfile = GetApplicationPath(outfile) + (width, height) = self.browser.GetSize(cefpython.PET_VIEW) + buffer = self.browser.GetImage(cefpython.PET_VIEW, width, height) + if ModuleExists("PIL"): + self.__SaveImageWithPil(buffer, width, height, outfile, format) + elif ModuleExists("pygame"): + self.__SaveImageWithPygame(buffer, width, height, outfile) + else: + print("Could not save image, no image library found (PIL, pygame)") + if os.path.exists(outfile): + os.system(outfile) + + def __SaveImageWithPil(self, buffer, width, height, outfile, format): + from PIL import Image + image = Image.fromstring( + "RGBA", (width,height), + buffer.GetString(mode="rgba", origin="top-left"), + "raw", "RGBA", 0, 1) + image.save(outfile, format) + + def __SaveImageWithPygame(self, buffer, width, height, outfile): + import pygame + # Format "PNG" is read from the filename. + surface = pygame.image.frombuffer( + buffer.GetString(mode="rgba", origin="top-left"), + (width, height), "RGBA") + pygame.image.save(surface, outfile) + + def ExecuteJavascript(self, jsCode): + self.browser.GetMainFrame().ExecuteJavascript(jsCode) + + def LoadUrl(self): + self.browser.GetMainFrame().LoadUrl( + GetApplicationPath("cefsimple.html")) + + def Version(self): + return sys.version + + def Test1(self, arg1): + print("python.Test1(%s) called" % arg1) + return ("This string was returned from python function python.Test1()" + " [unicode: ąś]") + + def Test2(self, arg1, arg2, arg3): + # ąś == b"\xc4\x85\xc5\x9b" + # ąś == u"\u0105\u015b" + # Displaying utf-8 characters to the console may result + # in UnicodeDecodeError, thus let's convert it to bytes + # and display the raw b"\xc4\x85\xc5\x9b" characters. + arg2_original = arg2 + if type(arg2) != bytes: + arg2 = arg2.encode(encoding="utf-8") + print("python.Test2(%s, '%s', '%s') called" % (arg1, arg2, arg3)) + # Testing nested return values. + return [1,2, [2.1, {'3': 3, '4': [5,6]}], "[unicode: ąś]", + arg2_original, arg2] + + def PrintPyConfig(self): + print("python.PrintPyConfig(): %s" % ( + self.browser.GetMainFrame().GetProperty("PyConfig"))) + + def ChangePyConfig(self): + self.browser.GetMainFrame().SetProperty("PyConfig", + "Changed in python during runtime in python.ChangePyConfig()") + + def TestJavascriptCallback(self, jsCallback): + if isinstance(jsCallback, cefpython.JavascriptCallback): + print("python.TestJavascriptCallback(): jsCallback.GetName(): " + "%s" % jsCallback.GetName()) + print("jsCallback.Call(1, [2,3], ('tuple', 'tuple'), " + "'unicode string')") + if bytes == str: + # Python 2.7 + jsCallback.Call(1, [2,3], ('tuple', 'tuple'), + unicode('unicode string [ąś]', encoding="utf-8")) + else: + # Python 3.2 - there is no "unicode()" in python 3 + jsCallback.Call(1, [2,3], ('tuple', 'tuple'), + 'unicode string [ąś]', + 'bytes string [ąś]'.encode('utf-8')) + else: + raise Exception("python.TestJavascriptCallback() failed: " + "given argument is not a javascript callback function") + + def TestPythonCallbackThroughReturn(self): + print("python.TestPythonCallbackThroughReturn() called, " + "returning PyCallback.") + return self.PyCallback + + def PyCallback(self, *args): + print("python.PyCallback() called, args: %s" % str(args)) + + def TestPythonCallbackThroughJavascriptCallback(self, jsCallback): + print("python.TestPythonCallbackThroughJavascriptCallback(jsCallback) " + "called") + print("jsCallback.Call(PyCallback)") + jsCallback.Call(self.PyCallback) + + def Alert(self, msg): + print("python.Alert() called instead of window.alert()") + win32gui.MessageBox(self.browser.GetUserData("outerWindowHandle"), + msg, "python.Alert()", win32con.MB_ICONQUESTION) + + def ChangeAlertDuringRuntime(self): + self.browser.GetMainFrame().SetProperty("alert", self.Alert2) + + def Alert2(self, msg): + print("python.Alert2() called instead of window.alert()") + win32gui.MessageBox(self.browser.GetUserData("outerWindowHandle"), + msg, "python.Alert2()", win32con.MB_ICONSTOP) + + def Find(self, searchText, findNext=False): + self.browser.Find(1, searchText, forward=True, matchCase=False, + findNext=findNext) + + def ResizeWindow(self): + cefwindow.MoveWindow(self.browser.GetUserData("outerWindowHandle"), + width=500, height=500) + + def MoveWindow(self): + cefwindow.MoveWindow(self.browser.GetUserData("outerWindowHandle"), + xpos=0, ypos=0) + + def GetType(self, arg1): + return "arg1=%s, type=%s" % (arg1, type(arg1).__name__) + + def CreateSecondBrowser(self): + # Closing second window won't quit application, + # WM_DESTROY not defined here. + wndproc2 = { + win32con.WM_CLOSE: CloseWindow, + win32con.WM_SIZE: cefpython.WindowUtils.OnSize, + win32con.WM_SETFOCUS: cefpython.WindowUtils.OnSetFocus, + win32con.WM_ERASEBKGND: cefpython.WindowUtils.OnEraseBackground + } + windowHandle2 = cefwindow.CreateWindow( + title="SecondBrowser", className="secondbrowser", + width=800, height=600, xpos=0, ypos=0, icon="icon.ico", + windowProc=wndproc2) + windowInfo2 = cefpython.WindowInfo() + windowInfo2.SetAsChild(windowHandle2) + browser2 = cefpython.CreateBrowserSync( + windowInfo2, browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + browser2.SetUserData("outerWindowHandle", windowHandle2) + + def GetUnicodeString(self): + if bytes == str: + # Python 2.7. Can't write u"This is unicode string \u2014" + # because Python 3 complains. + return unicode("This is unicode string \xe2\x80\x94".decode("utf-8")) + else: + return "Unicode string can be tested only in python 2.x" + + def TransparentPopup(self): + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsPopup(self.browser.GetWindowHandle(), "transparent") + windowInfo.SetTransparentPainting(True) + cefpython.CreateBrowserSync(windowInfo, browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + +if __name__ == "__main__": + CefAdvanced() diff --git a/cefpython/cef1/windows/binaries/cefclient_dcheck.bat b/cefpython/cef1/windows/binaries/cefclient_dcheck.bat new file mode 100644 index 00000000..0c23b8d5 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefclient_dcheck.bat @@ -0,0 +1,2 @@ +cefclient.exe -release-dcheck-enabled -log-severity=verbose +pause \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/cefpython_py27.py b/cefpython/cef1/windows/binaries/cefpython_py27.py new file mode 100644 index 00000000..0b0e988c --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefpython_py27.py @@ -0,0 +1,815 @@ +# This file contains API for the "cefpython.pyd" module, all functions are dummy. +# Use it as a quick reference. Use it for code completion in your IDE. +# This file does NOT need to be distribitued along with binaries. + +raise Exception("A dummy API file was imported instead of the PYD module.") + +""" +Detailed documentation with examples can be found on wiki pages: +http://code.google.com/p/cefpython/w/list +""" + +# Global functions in cefpython module. + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl): + return Browser() + +def FormatJavascriptStackTrace(stackTrace): + return "" + +def GetBrowserByWindowHandle(windowHandle): + return Browser() + +def GetJavascriptStackTrace(frameLimit=100): + return [] + +def Initialize(applicationSettings={}): + return None + +def IsKeyModifier(key, modifiers): + return False + +def MessageLoop(): + return None + +def MessageLoopWork(): + return None + +def QuitMessageLoop(): + return None + +def Shutdown(): + return None + +def GetModuleDirectory(): + return "" + +# +# Settings +# + +# Values are dummy, these are NOT the defaults. +ApplicationSettings = { + "auto_detect_proxy_settings_enabled": False, + "cache_path": "", + "extra_plugin_paths": [""], + "graphics_implementation": ANGLE_IN_PROCESS, + "javascript_flags": "", + "local_storage_quota": 5*1024*1024, + "locale": "", + "locales_dir_path": "", + "log_file": "", + "log_severity": LOGSEVERITY_INFO, + "release_dcheck_enabled": False, + "multi_threaded_message_loop": False, + "pack_loading_disabled": False, + "product_version": "", + "resources_dir_path": "", + "session_storage_quota": 5*1024*1024, + "string_encoding": "utf-8", + "uncaught_exception_stack_size": 0, + "user_agent": "", +} + +# ApplicationSettings["log_severity"] +LOGSEVERITY_VERBOSE = 0 +LOGSEVERITY_INFO = 0 +LOGSEVERITY_WARNING = 0 +LOGSEVERITY_ERROR = 0 +LOGSEVERITY_ERROR_REPORT = 0 +LOGSEVERITY_DISABLE = 0 + +# ApplicationSettings["graphics_implementation"] +ANGLE_IN_PROCESS = 0 +ANGLE_IN_PROCESS_COMMAND_BUFFER = 0 +DESKTOP_IN_PROCESS = 0 +DESKTOP_IN_PROCESS_COMMAND_BUFFER = 0 + +# Values are dummy, these are NOT the defaults. +BrowserSettings = { + "accelerated_2d_canvas_disabled": False, + "accelerated_compositing_enabled": False, + "accelerated_filters_disabled": False, + "accelerated_layers_disabled": False, + "accelerated_plugins_disabled": False, + "accelerated_video_disabled": False, + "animation_frame_rate": 0, + "application_cache_disabled": False, + "author_and_user_styles_disabled": False, + "caret_browsing_enabled": False, + "cursive_font_family": "", + "databases_disabled": False, + "default_encoding": "iso-8859-1", + "default_fixed_font_size": 0, + "default_font_size": 0, + "developer_tools_disabled": False, + "dom_paste_disabled": False, + "drag_drop_disabled": False, + "encoding_detector_enabled": False, + "fantasy_font_family": "", + "file_access_from_file_urls_allowed": False, + "fixed_font_family": "", + "fullscreen_enabled": False, + "history_disabled": False, + "hyperlink_auditing_disabled": False, + "image_load_disabled": False, + "java_disabled": False, + "javascript_access_clipboard_disallowed": False, + "javascript_close_windows_disallowed": False, + "javascript_disabled": False, + "javascript_open_windows_disallowed": False, + "load_drops_disabled": False, + "local_storage_disabled": False, + "minimum_font_size": 0, + "minimum_logical_font_size": 0, + "page_cache_disabled": False, + "plugins_disabled": False, + "remote_fonts_disabled": False, + "sans_serif_font_family": "", + "serif_font_family": "", + "shrink_standalone_images_to_fit": False, + "site_specific_quirks_disabled": False, + "standard_font_family": "", + "tab_to_links_disabled": False, + "text_area_resize_disabled": False, + "universal_access_from_file_urls_allowed": False, + "user_style_sheet_enabled": False, + "user_style_sheet_location": "", + "web_security_disabled": False, + "webgl_disabled": False, + "xss_auditor_enabled": False, +} + +# +# Browser object. +# + +class Browser: + + def CanGoBack(self): + return False + + def CanGoForward(self): + return False + + def ClearHistory(self): + return None + + def CloseBrowser(self): + return None + + def CloseDevTools(self): + return None + + def Find(self, searchID, searchText, forward, matchCase, findNext): + return None + + def GetClientCallback(self, name): + return callback + + def GetClientCallbacksDict(self): + return {} + + def GetFocusedFrame(self): + return Frame() + + def GetFrame(self): + return Frame() + + def GetFrameNames(self): + return ["", ""] + + def GetIdentifier(self): + return 0 + + def GetImage(self, paintElementType, width, height): + return PaintBuffer() + + def GetJavascriptBindings(self): + return JavascriptBindings() + + def GetMainFrame(self): + return Frame() + + def GetOpenerWindowHandle(self): + return 0 + + def GetOuterWindowHandle(self): + return 0 + + def GetSize(self, paintElementType): + return (0,0,) + + def GetUserData(self, key): + return None + + def GetWindowID(self): + return windowID + + def GetWindowHandle(self): + return 0 + + def GetZoomLevel(self): + return 0.0 + + def GoBack(self): + return None + + def GoForward(self): + return None + + def HasDocument(self): + return False + + def HidePopup(self): + return None + + def Invalidate(self, dirtyRect): + return None + + def IsFullscreen(self): + return False + + def IsPopup(self): + return False + + def IsPopupVisible(self): + return False + + def IsWindowRenderingDisabled(self): + return False + + def Reload(self): + return None + + def ReloadIgnoreCache(self): + return None + + def SendKeyEvent(self, keyType, keyInfo, modifiers): + return None + + def SendMouseClickEvent(self, x, y, mouseButtonType, mouseUp, clickCount): + return None + + def SendMouseMoveEvent(self, x, y, mouseLeave): + return None + + def SendMouseWheelEvent(self, x, y, deltaX, deltaY): + return None + + def SendFocusEvent(self, setFocus): + return None + + def SendCaptureLostEvent(self): + return None + + def SetClientCallback(self, name, callback): + return None + + def SetClientHandler(self, clientHandler): + return None + + def SetFocus(self, enable): + return None + + def SetJavascriptBindings(self, javascriptBindings): + return None + + def SetSize(self, paintElementType, width, height): + return None + + def SetZoomLevel(self, zoomLevel): + return None + + def SetUserData(self, key, value): + return None + + def ShowDevTools(self): + return None + + def StopLoad(self): + return None + + def StopFinding(self, clearSelection): + return None + + def ToggleFullscreen(self): + return None + +# +# Frame object. +# + +class Frame: + + def Copy(self): + return None + + def Cut(self): + return None + + def Delete(self): + return None + + def ExecuteJavascript(self, jsCode, scriptUrl=None, startLine=None): + return None + + def GetIdentifier(self): + return 0 + + def GetName(self): + return "" + + def GetProperty(self, name): + return mixed + + def GetSource(self): + return "" + + def GetText(self): + return "" + + def GetUrl(self): + return "" + + def IsFocused(self): + return False + + def IsMain(self): + return False + + def LoadString(self, value, url): + return None + + def LoadUrl(self, url): + return None + + def Paste(self): + return None + + def Print(self): + return None + + def Redo(self): + return None + + def SelectAll(self): + return None + + def SetProperty(self, name, value): + return None + + def Undo(self): + return None + + def ViewSource(self): + return None + +class Response: + + def GetStatus(self): + return 0 + + def SetStatus(self, status): + return None + + def GetStatusText(self): + return "" + + def SetStatusText(self, statusText): + return None + + def GetMimeType(self): + return "" + + def SetMimeType(self, mimeType): + return None + + def GetHeader(self, name): + return "" + + def GetHeaderMap(self): + return {} + + def GetHeaderMultimap(self): + return [("","")] + + def SetHeaderMap(self, headerMap={}): + return None + + def SetHeaderMultimap(self, headerMultimap=[]): + return None + +class PaintBuffer: + + def GetIntPointer(self): + return 0 + + def GetString(self, mode="bgra", origin="top-left"): + return "" + +class JavascriptBindings: + + def __init__(self, bindToFrames=False, bindToPopups=False): + return None + + def IsValueAllowed(self, value): + return False + + def Rebind(self): + return None + + def SetFunction(self, name, func): + return None + + def SetObject(self, name, obj): + return None + + def SetProperty(self, name, value): + return None + +class JavascriptCallback: + + def Call(self, param1, param2, param3_etc): + return mixed + + def GetName(self): + return name + +class WindowUtils: + + @staticmethod + def OnSetFocus(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnSize(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnEraseBackground(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def SetTitle(pyBrowser, pyTitle): + return None + + @staticmethod + def SetIcon(pyBrowser, icon="inherit"): + return None + +# +# DisplayHandler. +# + +# statusType constants (OnStatusMessage). +STATUSTYPE_TEXT = 0 +STATUSTYPE_MOUSEOVER_URL = 0 +STATUSTYPE_KEYBOARD_FOCUS_URL = 0 + +def DisplayHandler_OnAddressChange(browser, frame, url): + return None + +def DisplayHandler_OnConsoleMessage(browser, message, source, line): + return False + +def DisplayHandler_OnContentsSizeChange(browser, frame, width, height): + return None + +def DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward): + return None + +def DisplayHandler_OnStatusMessage(browser, text, statusType): + return None + +def DisplayHandler_OnTitleChange(browser, title): + return None + +def DisplayHandler_OnTooltip(browser, text_out=[""]): + return False + +# +# KeyboardHandler. +# + +def KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript): + return False + +# keyCode constants (OnKeyEvent). +VK_0=0x30 +VK_1=0x31 +VK_2=0x32 +VK_3=0x33 +VK_4=0x34 +VK_5=0x35 +VK_6=0x36 +VK_7=0x37 +VK_8=0x38 +VK_9=0x39 +VK_A=0x041 +VK_B=0x042 +VK_C=0x043 +VK_D=0x044 +VK_E=0x045 +VK_F=0x046 +VK_G=0x047 +VK_H=0x048 +VK_I=0x049 +VK_J=0x04A +VK_K=0x04B +VK_L=0x04C +VK_M=0x04D +VK_N=0x04E +VK_O=0x04F +VK_P=0x050 +VK_Q=0x051 +VK_R=0x052 +VK_S=0x053 +VK_T=0x054 +VK_U=0x055 +VK_V=0x056 +VK_W=0x057 +VK_X=0x058 +VK_Y=0x059 +VK_Z=0x05A +VK_F1=0x70 +VK_F2=0x71 +VK_F3=0x72 +VK_F4=0x73 +VK_F5=0x74 +VK_F6=0x75 +VK_F7=0x76 +VK_F8=0x77 +VK_F9=0x78 +VK_F10=0x79 +VK_F11=0x7A +VK_F12=0x7B +VK_F13=0x7C +VK_F14=0x7D +VK_F15=0x7E +VK_F16=0x7F +VK_F17=0x80 +VK_F18=0x81 +VK_F19=0x82 +VK_F20=0x83 +VK_F21=0x84 +VK_F22=0x85 +VK_F23=0x86 +VK_F24=0x87 +VK_LSHIFT=0xA0 +VK_RSHIFT=0xA1 +VK_LCONTROL=0xA2 +VK_RCONTROL=0xA3 +VK_LMENU=0xA4 +VK_RMENU=0xA5 +VK_BACK=0x08 +VK_TAB=0x09 +VK_SPACE=0x20 +VK_PRIOR=0x21 +VK_NEXT=0x22 +VK_END=0x23 +VK_HOME=0x24 +VK_LEFT=0x25 +VK_UP=0x26 +VK_RIGHT=0x27 +VK_DOWN=0x28 +VK_SELECT=0x29 +VK_PRINT=0x2A +VK_EXECUTE=0x2B +VK_SNAPSHOT=0x2C +VK_INSERT=0x2D +VK_DELETE=0x2E +VK_HELP=0x2F +VK_SHIFT=0x10 +VK_CONTROL=0x11 +VK_MENU=0x12 +VK_PAUSE=0x13 +VK_CAPITAL=0x14 +VK_CLEAR=0x0C +VK_RETURN=0x0D +VK_ESCAPE=0x1B +VK_LWIN=0x5B +VK_RWIN=0x5C +VK_APPS=0x5D +VK_SLEEP=0x5F +VK_NUMPAD0=0x60 +VK_NUMPAD1=0x61 +VK_NUMPAD2=0x62 +VK_NUMPAD3=0x63 +VK_NUMPAD4=0x64 +VK_NUMPAD5=0x65 +VK_NUMPAD6=0x66 +VK_NUMPAD7=0x67 +VK_NUMPAD8=0x68 +VK_NUMPAD9=0x69 +VK_BROWSER_BACK=0xA6 +VK_BROWSER_FORWARD=0xA7 +VK_BROWSER_REFRESH=0xA8 +VK_BROWSER_STOP=0xA9 +VK_BROWSER_SEARCH=0xAA +VK_BROWSER_FAVORITES=0xAB +VK_BROWSER_HOME=0xAC +VK_VOLUME_MUTE=0xAD +VK_VOLUME_DOWN=0xAE +VK_VOLUME_UP=0xAF +VK_MEDIA_NEXT_TRACK=0xB0 +VK_MEDIA_PREV_TRACK=0xB1 +VK_MEDIA_STOP=0xB2 +VK_MEDIA_PLAY_PAUSE=0xB3 +VK_LAUNCH_MAIL=0xB4 +VK_LAUNCH_MEDIA_SELECT=0xB5 +VK_LAUNCH_APP1=0xB6 +VK_LAUNCH_APP2=0xB7 +VK_MULTIPLY=0x6A +VK_ADD=0x6B +VK_SEPARATOR=0x6C +VK_SUBTRACT=0x6D +VK_DECIMAL=0x6E +VK_DIVIDE=0x6F +VK_NUMLOCK=0x90 +VK_SCROLL=0x91 +VK_LBUTTON=0x01 +VK_RBUTTON=0x02 +VK_CANCEL=0x03 +VK_MBUTTON=0x04 +VK_XBUTTON1=0x05 +VK_XBUTTON2=0x06 +VK_KANA=0x15 +VK_HANGEUL=0x15 +VK_HANGUL=0x15 +VK_JUNJA=0x17 +VK_FINAL=0x18 +VK_HANJA=0x19 +VK_KANJI=0x19 +VK_CONVERT=0x1C +VK_NONCONVERT=0x1D +VK_ACCEPT=0x1E +VK_MODECHANGE=0x1F +VK_PROCESSKEY=0xE5 +VK_PACKET=0xE7 +VK_ICO_HELP=0xE3 +VK_ICO_00=0xE4 +VK_ICO_CLEAR=0xE6 + +# eventType constants (OnKeyEvent). +KEYEVENT_RAWKEYDOWN = 0 +KEYEVENT_KEYDOWN = 0 +KEYEVENT_KEYUP = 0 +KEYEVENT_CHAR = 0 + +# Constants for checking modifiers param (OnKeyEvent), for use with IsKeyModifier() function. +KEY_NONE = 0 +KEY_SHIFT = 0 +KEY_CTRL = 0 +KEY_ALT = 0 +KEY_META = 0 +KEY_KEYPAD = 0 + +# +# LoadHandler. +# + +def LoadHandler_OnLoadEnd(browser, frame, httpStatusCode): + return None + +def LoadHandler_OnLoadError(browser, frame, errorCode, failedUrl, errorText_out=[""]): + return False + +def LoadHandler_OnLoadStart(browser, frame): + return None + +# errorCode constants (OnLoadError). +ERR_FAILED = 0 +ERR_ABORTED = 0 +ERR_INVALID_ARGUMENT = 0 +ERR_INVALID_HANDLE = 0 +ERR_FILE_NOT_FOUND = 0 +ERR_TIMED_OUT = 0 +ERR_FILE_TOO_BIG = 0 +ERR_UNEXPECTED = 0 +ERR_ACCESS_DENIED = 0 +ERR_NOT_IMPLEMENTED = 0 +ERR_CONNECTION_CLOSED = 0 +ERR_CONNECTION_RESET = 0 +ERR_CONNECTION_REFUSED = 0 +ERR_CONNECTION_ABORTED = 0 +ERR_CONNECTION_FAILED = 0 +ERR_NAME_NOT_RESOLVED = 0 +ERR_INTERNET_DISCONNECTED = 0 +ERR_SSL_PROTOCOL_ERROR = 0 +ERR_ADDRESS_INVALID = 0 +ERR_ADDRESS_UNREACHABLE = 0 +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = 0 +ERR_TUNNEL_CONNECTION_FAILED = 0 +ERR_NO_SSL_VERSIONS_ENABLED = 0 +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = 0 +ERR_SSL_RENEGOTIATION_REQUESTED = 0 +ERR_CERT_COMMON_NAME_INVALID = 0 +ERR_CERT_DATE_INVALID = 0 +ERR_CERT_AUTHORITY_INVALID = 0 +ERR_CERT_CONTAINS_ERRORS = 0 +ERR_CERT_NO_REVOCATION_MECHANISM = 0 +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 0 +ERR_CERT_REVOKED = 0 +ERR_CERT_INVALID = 0 +ERR_CERT_END = 0 +ERR_INVALID_URL = 0 +ERR_DISALLOWED_URL_SCHEME = 0 +ERR_UNKNOWN_URL_SCHEME = 0 +ERR_TOO_MANY_REDIRECTS = 0 +ERR_UNSAFE_REDIRECT = 0 +ERR_UNSAFE_PORT = 0 +ERR_INVALID_RESPONSE = 0 +ERR_INVALID_CHUNKED_ENCODING = 0 +ERR_METHOD_NOT_SUPPORTED = 0 +ERR_UNEXPECTED_PROXY_AUTH = 0 +ERR_EMPTY_RESPONSE = 0 +ERR_RESPONSE_HEADERS_TOO_BIG = 0 +ERR_CACHE_MISS = 0 +ERR_INSECURE_RESPONSE = 0 + +# +# RequestHandler. +# + +def RequestHandler_OnResourceRedirect(browser, oldUrl, newUrl_out=[""]): + return None + +def RequestHandler_OnResourceResponse(browser, url, response, filter_out=[None]): + return None + +def RequestHandler_OnProtocolExecution(browser, url, allowOSExecution_out=[False]): + return False + +def RequestHandler_GetAuthCredentials(browser, isProxy, host, port, realm, scheme, username_out=[""], password_out=[""]): + return False + +# navType constants (OnBeforeBrowse). +NAVTYPE_LINKCLICKED = 0 +NAVTYPE_FORMSUBMITTED = 0 +NAVTYPE_BACKFORWARD = 0 +NAVTYPE_RELOAD = 0 +NAVTYPE_FORMRESUBMITTED = 0 +NAVTYPE_OTHER = 0 +NAVTYPE_LINKDROPPED = 0 + +# +# JavascriptContextHandler +# + +def JavascriptContextHandler_OnUncaughtException(browser, frame, exception, stackTrace): + return None + +# +# LifespanHandler +# + +def LifespanHandler_DoClose(browser): + return False + +def LifespanHandler_OnAfterCreated(browser): + return None + +def LifespanHandler_OnBeforeClose(browser): + return None + +def LifespanHandler_RunModal(browser): + return False + +# +# RenderHandler +# + +PET_VIEW = 0 +PET_POPUP = 0 + +KEYTYPE_KEYUP = 0 +KEYTYPE_KEYDOWN = 0 +KEYTYPE_CHAR = 0 + +MOUSEBUTTON_LEFT = 0 +MOUSEBUTTON_MIDDLE = 0 +MOUSEBUTTON_RIGHT = 0 + +def RenderHandler_GetViewRect(browser, out_rect): + return False + +def RenderHandler_GetScreenRect(browser, out_rect): + return False + +def RenderHandler_GetScreenPoint(browser, viewX, viewY, out_screenCoordinates): + return False + +def RenderHandler_OnPopupShow(browser, show): + return None + +def RenderHandler_OnPopupSize(browser, rect): + return None + +def RenderHandler_OnPaint(browser, paintElementType, out_dirtyRects, + paintBuffer): + return None + +def RenderHandler_OnCursorChange(browser, cursor): + return None diff --git a/cefpython/cef1/windows/binaries/cefpython_py32.py b/cefpython/cef1/windows/binaries/cefpython_py32.py new file mode 100644 index 00000000..0b0e988c --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefpython_py32.py @@ -0,0 +1,815 @@ +# This file contains API for the "cefpython.pyd" module, all functions are dummy. +# Use it as a quick reference. Use it for code completion in your IDE. +# This file does NOT need to be distribitued along with binaries. + +raise Exception("A dummy API file was imported instead of the PYD module.") + +""" +Detailed documentation with examples can be found on wiki pages: +http://code.google.com/p/cefpython/w/list +""" + +# Global functions in cefpython module. + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl): + return Browser() + +def FormatJavascriptStackTrace(stackTrace): + return "" + +def GetBrowserByWindowHandle(windowHandle): + return Browser() + +def GetJavascriptStackTrace(frameLimit=100): + return [] + +def Initialize(applicationSettings={}): + return None + +def IsKeyModifier(key, modifiers): + return False + +def MessageLoop(): + return None + +def MessageLoopWork(): + return None + +def QuitMessageLoop(): + return None + +def Shutdown(): + return None + +def GetModuleDirectory(): + return "" + +# +# Settings +# + +# Values are dummy, these are NOT the defaults. +ApplicationSettings = { + "auto_detect_proxy_settings_enabled": False, + "cache_path": "", + "extra_plugin_paths": [""], + "graphics_implementation": ANGLE_IN_PROCESS, + "javascript_flags": "", + "local_storage_quota": 5*1024*1024, + "locale": "", + "locales_dir_path": "", + "log_file": "", + "log_severity": LOGSEVERITY_INFO, + "release_dcheck_enabled": False, + "multi_threaded_message_loop": False, + "pack_loading_disabled": False, + "product_version": "", + "resources_dir_path": "", + "session_storage_quota": 5*1024*1024, + "string_encoding": "utf-8", + "uncaught_exception_stack_size": 0, + "user_agent": "", +} + +# ApplicationSettings["log_severity"] +LOGSEVERITY_VERBOSE = 0 +LOGSEVERITY_INFO = 0 +LOGSEVERITY_WARNING = 0 +LOGSEVERITY_ERROR = 0 +LOGSEVERITY_ERROR_REPORT = 0 +LOGSEVERITY_DISABLE = 0 + +# ApplicationSettings["graphics_implementation"] +ANGLE_IN_PROCESS = 0 +ANGLE_IN_PROCESS_COMMAND_BUFFER = 0 +DESKTOP_IN_PROCESS = 0 +DESKTOP_IN_PROCESS_COMMAND_BUFFER = 0 + +# Values are dummy, these are NOT the defaults. +BrowserSettings = { + "accelerated_2d_canvas_disabled": False, + "accelerated_compositing_enabled": False, + "accelerated_filters_disabled": False, + "accelerated_layers_disabled": False, + "accelerated_plugins_disabled": False, + "accelerated_video_disabled": False, + "animation_frame_rate": 0, + "application_cache_disabled": False, + "author_and_user_styles_disabled": False, + "caret_browsing_enabled": False, + "cursive_font_family": "", + "databases_disabled": False, + "default_encoding": "iso-8859-1", + "default_fixed_font_size": 0, + "default_font_size": 0, + "developer_tools_disabled": False, + "dom_paste_disabled": False, + "drag_drop_disabled": False, + "encoding_detector_enabled": False, + "fantasy_font_family": "", + "file_access_from_file_urls_allowed": False, + "fixed_font_family": "", + "fullscreen_enabled": False, + "history_disabled": False, + "hyperlink_auditing_disabled": False, + "image_load_disabled": False, + "java_disabled": False, + "javascript_access_clipboard_disallowed": False, + "javascript_close_windows_disallowed": False, + "javascript_disabled": False, + "javascript_open_windows_disallowed": False, + "load_drops_disabled": False, + "local_storage_disabled": False, + "minimum_font_size": 0, + "minimum_logical_font_size": 0, + "page_cache_disabled": False, + "plugins_disabled": False, + "remote_fonts_disabled": False, + "sans_serif_font_family": "", + "serif_font_family": "", + "shrink_standalone_images_to_fit": False, + "site_specific_quirks_disabled": False, + "standard_font_family": "", + "tab_to_links_disabled": False, + "text_area_resize_disabled": False, + "universal_access_from_file_urls_allowed": False, + "user_style_sheet_enabled": False, + "user_style_sheet_location": "", + "web_security_disabled": False, + "webgl_disabled": False, + "xss_auditor_enabled": False, +} + +# +# Browser object. +# + +class Browser: + + def CanGoBack(self): + return False + + def CanGoForward(self): + return False + + def ClearHistory(self): + return None + + def CloseBrowser(self): + return None + + def CloseDevTools(self): + return None + + def Find(self, searchID, searchText, forward, matchCase, findNext): + return None + + def GetClientCallback(self, name): + return callback + + def GetClientCallbacksDict(self): + return {} + + def GetFocusedFrame(self): + return Frame() + + def GetFrame(self): + return Frame() + + def GetFrameNames(self): + return ["", ""] + + def GetIdentifier(self): + return 0 + + def GetImage(self, paintElementType, width, height): + return PaintBuffer() + + def GetJavascriptBindings(self): + return JavascriptBindings() + + def GetMainFrame(self): + return Frame() + + def GetOpenerWindowHandle(self): + return 0 + + def GetOuterWindowHandle(self): + return 0 + + def GetSize(self, paintElementType): + return (0,0,) + + def GetUserData(self, key): + return None + + def GetWindowID(self): + return windowID + + def GetWindowHandle(self): + return 0 + + def GetZoomLevel(self): + return 0.0 + + def GoBack(self): + return None + + def GoForward(self): + return None + + def HasDocument(self): + return False + + def HidePopup(self): + return None + + def Invalidate(self, dirtyRect): + return None + + def IsFullscreen(self): + return False + + def IsPopup(self): + return False + + def IsPopupVisible(self): + return False + + def IsWindowRenderingDisabled(self): + return False + + def Reload(self): + return None + + def ReloadIgnoreCache(self): + return None + + def SendKeyEvent(self, keyType, keyInfo, modifiers): + return None + + def SendMouseClickEvent(self, x, y, mouseButtonType, mouseUp, clickCount): + return None + + def SendMouseMoveEvent(self, x, y, mouseLeave): + return None + + def SendMouseWheelEvent(self, x, y, deltaX, deltaY): + return None + + def SendFocusEvent(self, setFocus): + return None + + def SendCaptureLostEvent(self): + return None + + def SetClientCallback(self, name, callback): + return None + + def SetClientHandler(self, clientHandler): + return None + + def SetFocus(self, enable): + return None + + def SetJavascriptBindings(self, javascriptBindings): + return None + + def SetSize(self, paintElementType, width, height): + return None + + def SetZoomLevel(self, zoomLevel): + return None + + def SetUserData(self, key, value): + return None + + def ShowDevTools(self): + return None + + def StopLoad(self): + return None + + def StopFinding(self, clearSelection): + return None + + def ToggleFullscreen(self): + return None + +# +# Frame object. +# + +class Frame: + + def Copy(self): + return None + + def Cut(self): + return None + + def Delete(self): + return None + + def ExecuteJavascript(self, jsCode, scriptUrl=None, startLine=None): + return None + + def GetIdentifier(self): + return 0 + + def GetName(self): + return "" + + def GetProperty(self, name): + return mixed + + def GetSource(self): + return "" + + def GetText(self): + return "" + + def GetUrl(self): + return "" + + def IsFocused(self): + return False + + def IsMain(self): + return False + + def LoadString(self, value, url): + return None + + def LoadUrl(self, url): + return None + + def Paste(self): + return None + + def Print(self): + return None + + def Redo(self): + return None + + def SelectAll(self): + return None + + def SetProperty(self, name, value): + return None + + def Undo(self): + return None + + def ViewSource(self): + return None + +class Response: + + def GetStatus(self): + return 0 + + def SetStatus(self, status): + return None + + def GetStatusText(self): + return "" + + def SetStatusText(self, statusText): + return None + + def GetMimeType(self): + return "" + + def SetMimeType(self, mimeType): + return None + + def GetHeader(self, name): + return "" + + def GetHeaderMap(self): + return {} + + def GetHeaderMultimap(self): + return [("","")] + + def SetHeaderMap(self, headerMap={}): + return None + + def SetHeaderMultimap(self, headerMultimap=[]): + return None + +class PaintBuffer: + + def GetIntPointer(self): + return 0 + + def GetString(self, mode="bgra", origin="top-left"): + return "" + +class JavascriptBindings: + + def __init__(self, bindToFrames=False, bindToPopups=False): + return None + + def IsValueAllowed(self, value): + return False + + def Rebind(self): + return None + + def SetFunction(self, name, func): + return None + + def SetObject(self, name, obj): + return None + + def SetProperty(self, name, value): + return None + +class JavascriptCallback: + + def Call(self, param1, param2, param3_etc): + return mixed + + def GetName(self): + return name + +class WindowUtils: + + @staticmethod + def OnSetFocus(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnSize(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnEraseBackground(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def SetTitle(pyBrowser, pyTitle): + return None + + @staticmethod + def SetIcon(pyBrowser, icon="inherit"): + return None + +# +# DisplayHandler. +# + +# statusType constants (OnStatusMessage). +STATUSTYPE_TEXT = 0 +STATUSTYPE_MOUSEOVER_URL = 0 +STATUSTYPE_KEYBOARD_FOCUS_URL = 0 + +def DisplayHandler_OnAddressChange(browser, frame, url): + return None + +def DisplayHandler_OnConsoleMessage(browser, message, source, line): + return False + +def DisplayHandler_OnContentsSizeChange(browser, frame, width, height): + return None + +def DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward): + return None + +def DisplayHandler_OnStatusMessage(browser, text, statusType): + return None + +def DisplayHandler_OnTitleChange(browser, title): + return None + +def DisplayHandler_OnTooltip(browser, text_out=[""]): + return False + +# +# KeyboardHandler. +# + +def KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript): + return False + +# keyCode constants (OnKeyEvent). +VK_0=0x30 +VK_1=0x31 +VK_2=0x32 +VK_3=0x33 +VK_4=0x34 +VK_5=0x35 +VK_6=0x36 +VK_7=0x37 +VK_8=0x38 +VK_9=0x39 +VK_A=0x041 +VK_B=0x042 +VK_C=0x043 +VK_D=0x044 +VK_E=0x045 +VK_F=0x046 +VK_G=0x047 +VK_H=0x048 +VK_I=0x049 +VK_J=0x04A +VK_K=0x04B +VK_L=0x04C +VK_M=0x04D +VK_N=0x04E +VK_O=0x04F +VK_P=0x050 +VK_Q=0x051 +VK_R=0x052 +VK_S=0x053 +VK_T=0x054 +VK_U=0x055 +VK_V=0x056 +VK_W=0x057 +VK_X=0x058 +VK_Y=0x059 +VK_Z=0x05A +VK_F1=0x70 +VK_F2=0x71 +VK_F3=0x72 +VK_F4=0x73 +VK_F5=0x74 +VK_F6=0x75 +VK_F7=0x76 +VK_F8=0x77 +VK_F9=0x78 +VK_F10=0x79 +VK_F11=0x7A +VK_F12=0x7B +VK_F13=0x7C +VK_F14=0x7D +VK_F15=0x7E +VK_F16=0x7F +VK_F17=0x80 +VK_F18=0x81 +VK_F19=0x82 +VK_F20=0x83 +VK_F21=0x84 +VK_F22=0x85 +VK_F23=0x86 +VK_F24=0x87 +VK_LSHIFT=0xA0 +VK_RSHIFT=0xA1 +VK_LCONTROL=0xA2 +VK_RCONTROL=0xA3 +VK_LMENU=0xA4 +VK_RMENU=0xA5 +VK_BACK=0x08 +VK_TAB=0x09 +VK_SPACE=0x20 +VK_PRIOR=0x21 +VK_NEXT=0x22 +VK_END=0x23 +VK_HOME=0x24 +VK_LEFT=0x25 +VK_UP=0x26 +VK_RIGHT=0x27 +VK_DOWN=0x28 +VK_SELECT=0x29 +VK_PRINT=0x2A +VK_EXECUTE=0x2B +VK_SNAPSHOT=0x2C +VK_INSERT=0x2D +VK_DELETE=0x2E +VK_HELP=0x2F +VK_SHIFT=0x10 +VK_CONTROL=0x11 +VK_MENU=0x12 +VK_PAUSE=0x13 +VK_CAPITAL=0x14 +VK_CLEAR=0x0C +VK_RETURN=0x0D +VK_ESCAPE=0x1B +VK_LWIN=0x5B +VK_RWIN=0x5C +VK_APPS=0x5D +VK_SLEEP=0x5F +VK_NUMPAD0=0x60 +VK_NUMPAD1=0x61 +VK_NUMPAD2=0x62 +VK_NUMPAD3=0x63 +VK_NUMPAD4=0x64 +VK_NUMPAD5=0x65 +VK_NUMPAD6=0x66 +VK_NUMPAD7=0x67 +VK_NUMPAD8=0x68 +VK_NUMPAD9=0x69 +VK_BROWSER_BACK=0xA6 +VK_BROWSER_FORWARD=0xA7 +VK_BROWSER_REFRESH=0xA8 +VK_BROWSER_STOP=0xA9 +VK_BROWSER_SEARCH=0xAA +VK_BROWSER_FAVORITES=0xAB +VK_BROWSER_HOME=0xAC +VK_VOLUME_MUTE=0xAD +VK_VOLUME_DOWN=0xAE +VK_VOLUME_UP=0xAF +VK_MEDIA_NEXT_TRACK=0xB0 +VK_MEDIA_PREV_TRACK=0xB1 +VK_MEDIA_STOP=0xB2 +VK_MEDIA_PLAY_PAUSE=0xB3 +VK_LAUNCH_MAIL=0xB4 +VK_LAUNCH_MEDIA_SELECT=0xB5 +VK_LAUNCH_APP1=0xB6 +VK_LAUNCH_APP2=0xB7 +VK_MULTIPLY=0x6A +VK_ADD=0x6B +VK_SEPARATOR=0x6C +VK_SUBTRACT=0x6D +VK_DECIMAL=0x6E +VK_DIVIDE=0x6F +VK_NUMLOCK=0x90 +VK_SCROLL=0x91 +VK_LBUTTON=0x01 +VK_RBUTTON=0x02 +VK_CANCEL=0x03 +VK_MBUTTON=0x04 +VK_XBUTTON1=0x05 +VK_XBUTTON2=0x06 +VK_KANA=0x15 +VK_HANGEUL=0x15 +VK_HANGUL=0x15 +VK_JUNJA=0x17 +VK_FINAL=0x18 +VK_HANJA=0x19 +VK_KANJI=0x19 +VK_CONVERT=0x1C +VK_NONCONVERT=0x1D +VK_ACCEPT=0x1E +VK_MODECHANGE=0x1F +VK_PROCESSKEY=0xE5 +VK_PACKET=0xE7 +VK_ICO_HELP=0xE3 +VK_ICO_00=0xE4 +VK_ICO_CLEAR=0xE6 + +# eventType constants (OnKeyEvent). +KEYEVENT_RAWKEYDOWN = 0 +KEYEVENT_KEYDOWN = 0 +KEYEVENT_KEYUP = 0 +KEYEVENT_CHAR = 0 + +# Constants for checking modifiers param (OnKeyEvent), for use with IsKeyModifier() function. +KEY_NONE = 0 +KEY_SHIFT = 0 +KEY_CTRL = 0 +KEY_ALT = 0 +KEY_META = 0 +KEY_KEYPAD = 0 + +# +# LoadHandler. +# + +def LoadHandler_OnLoadEnd(browser, frame, httpStatusCode): + return None + +def LoadHandler_OnLoadError(browser, frame, errorCode, failedUrl, errorText_out=[""]): + return False + +def LoadHandler_OnLoadStart(browser, frame): + return None + +# errorCode constants (OnLoadError). +ERR_FAILED = 0 +ERR_ABORTED = 0 +ERR_INVALID_ARGUMENT = 0 +ERR_INVALID_HANDLE = 0 +ERR_FILE_NOT_FOUND = 0 +ERR_TIMED_OUT = 0 +ERR_FILE_TOO_BIG = 0 +ERR_UNEXPECTED = 0 +ERR_ACCESS_DENIED = 0 +ERR_NOT_IMPLEMENTED = 0 +ERR_CONNECTION_CLOSED = 0 +ERR_CONNECTION_RESET = 0 +ERR_CONNECTION_REFUSED = 0 +ERR_CONNECTION_ABORTED = 0 +ERR_CONNECTION_FAILED = 0 +ERR_NAME_NOT_RESOLVED = 0 +ERR_INTERNET_DISCONNECTED = 0 +ERR_SSL_PROTOCOL_ERROR = 0 +ERR_ADDRESS_INVALID = 0 +ERR_ADDRESS_UNREACHABLE = 0 +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = 0 +ERR_TUNNEL_CONNECTION_FAILED = 0 +ERR_NO_SSL_VERSIONS_ENABLED = 0 +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = 0 +ERR_SSL_RENEGOTIATION_REQUESTED = 0 +ERR_CERT_COMMON_NAME_INVALID = 0 +ERR_CERT_DATE_INVALID = 0 +ERR_CERT_AUTHORITY_INVALID = 0 +ERR_CERT_CONTAINS_ERRORS = 0 +ERR_CERT_NO_REVOCATION_MECHANISM = 0 +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 0 +ERR_CERT_REVOKED = 0 +ERR_CERT_INVALID = 0 +ERR_CERT_END = 0 +ERR_INVALID_URL = 0 +ERR_DISALLOWED_URL_SCHEME = 0 +ERR_UNKNOWN_URL_SCHEME = 0 +ERR_TOO_MANY_REDIRECTS = 0 +ERR_UNSAFE_REDIRECT = 0 +ERR_UNSAFE_PORT = 0 +ERR_INVALID_RESPONSE = 0 +ERR_INVALID_CHUNKED_ENCODING = 0 +ERR_METHOD_NOT_SUPPORTED = 0 +ERR_UNEXPECTED_PROXY_AUTH = 0 +ERR_EMPTY_RESPONSE = 0 +ERR_RESPONSE_HEADERS_TOO_BIG = 0 +ERR_CACHE_MISS = 0 +ERR_INSECURE_RESPONSE = 0 + +# +# RequestHandler. +# + +def RequestHandler_OnResourceRedirect(browser, oldUrl, newUrl_out=[""]): + return None + +def RequestHandler_OnResourceResponse(browser, url, response, filter_out=[None]): + return None + +def RequestHandler_OnProtocolExecution(browser, url, allowOSExecution_out=[False]): + return False + +def RequestHandler_GetAuthCredentials(browser, isProxy, host, port, realm, scheme, username_out=[""], password_out=[""]): + return False + +# navType constants (OnBeforeBrowse). +NAVTYPE_LINKCLICKED = 0 +NAVTYPE_FORMSUBMITTED = 0 +NAVTYPE_BACKFORWARD = 0 +NAVTYPE_RELOAD = 0 +NAVTYPE_FORMRESUBMITTED = 0 +NAVTYPE_OTHER = 0 +NAVTYPE_LINKDROPPED = 0 + +# +# JavascriptContextHandler +# + +def JavascriptContextHandler_OnUncaughtException(browser, frame, exception, stackTrace): + return None + +# +# LifespanHandler +# + +def LifespanHandler_DoClose(browser): + return False + +def LifespanHandler_OnAfterCreated(browser): + return None + +def LifespanHandler_OnBeforeClose(browser): + return None + +def LifespanHandler_RunModal(browser): + return False + +# +# RenderHandler +# + +PET_VIEW = 0 +PET_POPUP = 0 + +KEYTYPE_KEYUP = 0 +KEYTYPE_KEYDOWN = 0 +KEYTYPE_CHAR = 0 + +MOUSEBUTTON_LEFT = 0 +MOUSEBUTTON_MIDDLE = 0 +MOUSEBUTTON_RIGHT = 0 + +def RenderHandler_GetViewRect(browser, out_rect): + return False + +def RenderHandler_GetScreenRect(browser, out_rect): + return False + +def RenderHandler_GetScreenPoint(browser, viewX, viewY, out_screenCoordinates): + return False + +def RenderHandler_OnPopupShow(browser, show): + return None + +def RenderHandler_OnPopupSize(browser, rect): + return None + +def RenderHandler_OnPaint(browser, paintElementType, out_dirtyRects, + paintBuffer): + return None + +def RenderHandler_OnCursorChange(browser, cursor): + return None diff --git a/cefpython/cef1/windows/binaries/cefsimple.html b/cefpython/cef1/windows/binaries/cefsimple.html new file mode 100644 index 00000000..f46f773c --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefsimple.html @@ -0,0 +1,37 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Welcome to CEF Python - bindings for the Chromium Embedded Framework.

+ +Project's website: http://code.google.com/p/cefpython/
+Wiki documentation: http://code.google.com/p/cefpython/wiki/
+Support forum: https://groups.google.com/group/cefpython?hl=en
+ +

Google Search

+ +http://www.google.com/ + +

User agent

+ + + +

Popup

+ + + window.open('cefsimple.html') + +










+










+










+ + + diff --git a/cefpython/cef1/windows/binaries/cefsimple.py b/cefpython/cef1/windows/binaries/cefsimple.py new file mode 100644 index 00000000..966de180 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefsimple.py @@ -0,0 +1,109 @@ +# Simple CEF Python application, +# for more advanced features see "cefadvanced.py" + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import cefwindow +import win32con +import win32gui + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +def CefSimple(): + sys.excepthook = ExceptHook + cefpython.g_debug = True + cefpython.Initialize() + wndproc = { + win32con.WM_CLOSE: CloseWindow, + win32con.WM_DESTROY: QuitApplication, + win32con.WM_SIZE: cefpython.WindowUtils.OnSize, + win32con.WM_SETFOCUS: cefpython.WindowUtils.OnSetFocus, + win32con.WM_ERASEBKGND: cefpython.WindowUtils.OnEraseBackground } + windowHandle = cefwindow.CreateWindow( + title="CefSimple", className="cefsimple", width=800, height=600, + icon="icon.ico", windowProc=wndproc) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowHandle) + browser = cefpython.CreateBrowserSync( + windowInfo, browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + cefpython.MessageLoop() + cefpython.Shutdown() + +def CloseWindow(windowHandle, message, wparam, lparam): + browser = cefpython.GetBrowserByWindowHandle(windowHandle) + browser.CloseBrowser() + return win32gui.DefWindowProc(windowHandle, message, wparam, lparam) + +def QuitApplication(windowHandle, message, wparam, lparam): + win32gui.PostQuitMessage(0) + return 0 + +if __name__ == "__main__": + CefSimple() diff --git a/cefpython/cef1/windows/binaries/cefwindow.py b/cefpython/cef1/windows/binaries/cefwindow.py new file mode 100644 index 00000000..fd0ac73e --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefwindow.py @@ -0,0 +1,205 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +import win32gui +import win32con +import win32api +import time +import math +import os +import sys +import re + +if sys.version_info.major == 2: + from urllib import pathname2url as urllib_pathname2url +else: + from urllib.request import pathname2url as urllib_pathname2url + +g_debug = False +g_windows = {} # windowID(int): className +g_registeredClasses = {} + +def Debug(msg): + + if not g_debug: + return + msg = "cefwindow: "+str(msg) + print(msg) + with open(GetRealPath("debug.log"), "a") as file: + file.write(msg+"\n") + +def GetRealPath(file=None, encodeURL=False): + + # This function is defined in 2 files: cefpython.pyx and cefwindow.py, if you make changes edit both files. + # If file is None return current directory, without trailing slash. + + # encodeURL param - will call urllib.pathname2url(), only when file is empty (current dir) + # or is relative path ("test.html", "some/test.html"), we need to encode it before passing + # to CreateBrowser(), otherwise it is encoded by CEF internally and becomes (chinese characters): + # >> %EF%BF%97%EF%BF%80%EF%BF%83%EF%BF%A6 + # but should be: + # >> %E6%A1%8C%E9%9D%A2 + + if file is None: file = "" + if file.find("/") != 0 and file.find("\\") != 0 and not re.search(r"^[a-zA-Z]+:[/\\]?", file): + # Execute this block only when relative path ("test.html", "some\test.html") or file is empty (current dir). + # 1. find != 0 >> not starting with / or \ (/ - linux absolute path, \ - just to be sure) + # 2. not re.search >> not (D:\\ or D:/ or D: or http:// or ftp:// or file://), + # "D:" is also valid absolute path ("D:cefpython" in chrome becomes "file:///D:/cefpython/") + if hasattr(sys, "frozen"): path = os.path.dirname(sys.executable) + elif "__file__" in globals(): path = os.path.dirname(os.path.realpath(__file__)) + else: path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) # directory without trailing slash. + if encodeURL: + return urllib_pathname2url(path) + else: + return path + return file + +def CreateWindow(title, className, width, height, xpos=None, ypos=None, icon=None, windowProc=None): + + """ + for key in g_windows: + if g_windows[key] == className: + raise Exception("There was already created a window with that className: %s." + "Each created window must have an unique className." % className) + """ + + if not windowProc: + windowProc = {win32con.WM_CLOSE: WM_CLOSE} + + bigIcon = "" + smallIcon = "" + + if icon: + icon = GetRealPath(icon) + + # Load small and big icon. + # WNDCLASSEX (along with hIconSm) is not supported by pywin32, + # we need to use WM_SETICON message after window creation. + + # http://stackoverflow.com/questions/2234988/how-to-set-hicon-on-a-window-ico-with-multiple-sizes + # http://blog.barthe.ph/2009/07/17/wmseticon/ + + bigX = win32api.GetSystemMetrics(win32con.SM_CXICON) + bigY = win32api.GetSystemMetrics(win32con.SM_CYICON) + bigIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, bigX, bigY, win32con.LR_LOADFROMFILE) + smallX = win32api.GetSystemMetrics(win32con.SM_CXSMICON) + smallY = win32api.GetSystemMetrics(win32con.SM_CYSMICON) + smallIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, smallX, smallY, win32con.LR_LOADFROMFILE) + + wndclass = win32gui.WNDCLASS() + wndclass.hInstance = win32api.GetModuleHandle(None) + wndclass.lpszClassName = className + wndclass.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW + # win32con.CS_GLOBALCLASS + wndclass.hbrBackground = win32con.COLOR_WINDOW + wndclass.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) + wndclass.lpfnWndProc = windowProc + + #noinspection PyUnusedLocal + global g_registeredClasses + if not className in g_registeredClasses: + g_registeredClasses[className] = True + atomclass = win32gui.RegisterClass(wndclass) + Debug("win32gui.RegisterClass(%s)" % className) + + if xpos is None or ypos is None: + # Center window on the screen. + Debug("Centering window on the screen.") + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + + windowID = win32gui.CreateWindow(className, title, + win32con.WS_OVERLAPPEDWINDOW | win32con.WS_CLIPCHILDREN | win32con.WS_VISIBLE, + xpos, ypos, width, height, # xpos, ypos, width, height + 0, 0, wndclass.hInstance, None) + g_windows[windowID] = className + + if icon: + if bigIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_BIG, bigIcon) + if smallIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_SMALL, smallIcon) + + Debug("windowID = %s" % windowID) + return windowID + + +# Memory error when calling win32gui.DestroyWindow() +# after we called cefpython.CloseBrowser() + +def DestroyWindow(windowID): + + win32gui.DestroyWindow(windowID) + #className = GetWindowClassName(windowID) + #win32gui.UnregisterClass(className, None) + #del g_windows[windowID] # Let window with this className be created again. + + +def GetWindowClassName(windowID): + + for key in g_windows: + if key == windowID: + return g_windows[key] + +def MoveWindow(windowID, xpos=None, ypos=None, width=None, height=None, center=None): + + (left, top, right, bottom) = win32gui.GetWindowRect(windowID) + if xpos is None and ypos is None: + xpos = left + ypos = top + if width is None and height is None: + width = right - left + height = bottom - top + # Case: only ypos provided + if xpos is None and ypos is not None: + xpos = left + if ypos is None and xpos is not None: + ypos = top + # Case: only height provided + if not width: + width = right - left + if not height: + height = bottom - top + if center: + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + win32gui.MoveWindow(windowID, xpos, ypos, width, height, 1) + + +#noinspection PyUnusedLocal +def WM_CLOSE(windowID, msg, wparam, lparam): + + DestroyWindow(windowID) + win32gui.PostQuitMessage(0) + + +def GetLastError(): + + code = win32api.GetLastError() + return "(%d) %s" % (code, win32api.FormatMessage(code)) + +#noinspection PyUnusedLocal +def MessageLoop(className): + + while not win32gui.PumpWaitingMessages(): + time.sleep(0.001) + + +if __name__ == "__main__": + + g_debug = True + hwnd = CreateWindow("Test window", "testwindow", 800, 600) + MessageLoop("testwindow") \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/cefwxpanel.py b/cefpython/cef1/windows/binaries/cefwxpanel.py new file mode 100644 index 00000000..e53f52d3 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefwxpanel.py @@ -0,0 +1,147 @@ +# Additional wx specific layer of abstraction for the cefpython +# __author__ = "Greg Kacy " + +#------------------------------------------------------------------------------- + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import wx + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +#------------------------------------------------------------------------------- + +TIMER_MILLIS = 10 + +#------------------------------------------------------------------------------- + +class CEFWindow(wx.Window): + """Standalone CEF component. The class provides facilites for interacting with wx message loop""" + def __init__(self, parent, url="", size=(-1, -1), *args, **kwargs): + wx.Window.__init__(self, parent, id=wx.ID_ANY, size=size, *args, **kwargs) + self.url = url + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.GetHandle()) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, navigateUrl=url) + + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + + self.timerID = 1 + self._createTimer() + + def GetBrowser(self): + '''Returns the CEF's browser object''' + return self.browser + + def __del__(self): + '''cleanup stuff''' + self.timer.Stop() + self.browser.CloseBrowser() + + def _createTimer(self): + # this timer's events services the SEF message loops + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(TIMER_MILLIS) # + wx.EVT_TIMER(self, self.timerID, self._onTimer) + + def _onTimer(self, event): + """Service CEF message loop""" + cefpython.MessageLoopWork() + + def OnSetFocus(self, event): + cefpython.WindowUtils.OnSetFocus(self.GetHandle(), 0, 0, 0) + + def OnSize(self, event): + cefpython.WindowUtils.OnSize(self.GetHandle(), 0, 0, 0) + + #def Shutdown(self): + #print "CLOSING PAGE %s, YA MAN" % self.url + #self.timer.Stop() + #self.browser.CloseBrowser() + +#------------------------------------------------------------------------------- + +def initCEF(settings=None): + """Initializes CEF, We should do it before initializing wx + If no settings passed a default is used + """ + sys.excepthook = ExceptHook + if not settings: + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + +def shutdownCEF(): + """Shuts down CEF, should be called by app exiting code""" + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/binaries/cefwxpanel_sample1.py b/cefpython/cef1/windows/binaries/cefwxpanel_sample1.py new file mode 100644 index 00000000..1aff0404 --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefwxpanel_sample1.py @@ -0,0 +1,33 @@ +# Simple sample ilustrating the usage of CEFWindow class +# __author__ = "Greg Kacy " + +import wx + +from cefwxpanel import initCEF, shutdownCEF, CEFWindow, GetApplicationPath + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, title='wxPython example', size=(600,400)) + + self.cefPanel = CEFWindow(self, + url=GetApplicationPath("cefsimple.html")) + + sizer = wx.BoxSizer() + sizer.Add(self.cefPanel, 1, wx.EXPAND, 0) + self.SetSizer(sizer) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + self.Destroy() + +if __name__ == '__main__': + initCEF() + print('wx.version=%s' % wx.version()) + app = wx.PySimpleApp() + MainFrame().Show() + app.MainLoop() + del app # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + shutdownCEF() + + diff --git a/cefpython/cef1/windows/binaries/cefwxpanel_sample2.py b/cefpython/cef1/windows/binaries/cefwxpanel_sample2.py new file mode 100644 index 00000000..c7283e5f --- /dev/null +++ b/cefpython/cef1/windows/binaries/cefwxpanel_sample2.py @@ -0,0 +1,70 @@ +# Slightly more advanced sample illustrating the usage of CEFWindow class +# __author__ = "Greg Kacy " + +import wx +import wx.lib.agw.flatnotebook as fnb + +from cefwxpanel import initCEF, shutdownCEF, CEFWindow, GetApplicationPath + +ROOT_NAME = "My Locations" + +URLS = ["http://google.com", + "http://maps.google.com", + "http://youtube.com", + "http://yahoo.com", + "http://wikipedia.com", + "http://cyaninc.com", + ] + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, title='wxPython example', size=(600,400)) + self.initComponents() + self.layoutComponents() + self.initEventHandlers() + + def initComponents(self): + self.tree = wx.TreeCtrl(self, id=-1, size=(200, -1)) + self.root = self.tree.AddRoot(ROOT_NAME) + for url in URLS: + self.tree.AppendItem(self.root, url) + self.tree.Expand(self.root) + + self.tabs = fnb.FlatNotebook(self, wx.ID_ANY, agwStyle=fnb.FNB_NODRAG|fnb.FNB_X_ON_TAB) + + def layoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.tree, 0, wx.EXPAND) + sizer.Add(self.tabs, 1, wx.EXPAND) + self.SetSizer(sizer) + + def initEventHandlers(self): + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree) + self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosing) + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnSelChanged(self, event): + self.item = event.GetItem() + url = self.tree.GetItemText(self.item) + if url and url != ROOT_NAME: + cefPanel = CEFWindow(self.tabs, url=str(url)) + self.tabs.AddPage(cefPanel, url) + self.tabs.SetSelection(self.tabs.GetPageCount()-1) + event.Skip() + + def OnPageClosing(self, event): + print "One could place some extra closing stuff here" + event.Skip() + + def OnClose(self, event): + self.Destroy() + +if __name__ == '__main__': + initCEF() + print('wx.version=%s' % wx.version()) + app = wx.PySimpleApp() + MainFrame().Show() + app.MainLoop() + del app # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + shutdownCEF() + diff --git a/cefpython/cef1/windows/binaries/debug_gdb.bat b/cefpython/cef1/windows/binaries/debug_gdb.bat new file mode 100644 index 00000000..cde0af22 --- /dev/null +++ b/cefpython/cef1/windows/binaries/debug_gdb.bat @@ -0,0 +1,7 @@ +setlocal +set PATH=%PATH%;C:\mingw\bin;C:\python27 +C:\mingw\bin\gdb.exe --args C:\python27\python.exe %~dp0cefadvanced.py +REM type "run" +REM if error occurs type "backtrace" +REM type "help" for more commands +pause \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/debug_pdb.bat b/cefpython/cef1/windows/binaries/debug_pdb.bat new file mode 100644 index 00000000..9a64357a --- /dev/null +++ b/cefpython/cef1/windows/binaries/debug_pdb.bat @@ -0,0 +1,3 @@ +python -m pdb cefadvanced.py +REM type "continue" or "help" +pause \ No newline at end of file diff --git a/cefpython/cef1/windows/binaries/icon.ico b/cefpython/cef1/windows/binaries/icon.ico new file mode 100644 index 00000000..435045ae Binary files /dev/null and b/cefpython/cef1/windows/binaries/icon.ico differ diff --git a/cefpython/cef1/windows/binaries/msvcm90.dll b/cefpython/cef1/windows/binaries/msvcm90.dll new file mode 100644 index 00000000..b9cb1231 Binary files /dev/null and b/cefpython/cef1/windows/binaries/msvcm90.dll differ diff --git a/cefpython/cef1/windows/binaries/msvcp90.dll b/cefpython/cef1/windows/binaries/msvcp90.dll new file mode 100644 index 00000000..6b07c75a Binary files /dev/null and b/cefpython/cef1/windows/binaries/msvcp90.dll differ diff --git a/cefpython/cef1/windows/binaries/msvcr90.dll b/cefpython/cef1/windows/binaries/msvcr90.dll new file mode 100644 index 00000000..a68249aa Binary files /dev/null and b/cefpython/cef1/windows/binaries/msvcr90.dll differ diff --git a/cefpython/cef1/windows/binaries/panda3d_.py b/cefpython/cef1/windows/binaries/panda3d_.py new file mode 100644 index 00000000..d03b6467 --- /dev/null +++ b/cefpython/cef1/windows/binaries/panda3d_.py @@ -0,0 +1,417 @@ +# CEF off-screen rendering using the Panda3D game engine: +# http://www.panda3d.org/ + +# You need panda3D SDK that is compatible with python 2.7, +# version 1.8.0 comes by default with python 2.7. + +# To use custom python (not the one provided with the SDK) +# create a "panda.pth" file inside your copy of python, in +# this file put paths to panda & bin directory on separate +# lines, for example: +# +# c:\Panda3D-1.8.0 +# c:\Panda3D-1.8.0\bin +# +# This will enable your copy of python to find the panda libraries. + +# TODO: fix the blurriness of the browser when window is resized. + +TEST_TRANSPARENCY = False + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +from pandac.PandaModules import loadPrcFileData +loadPrcFileData("", "Panda3D example") +loadPrcFileData("", "fullscreen 0") +loadPrcFileData("", "win-size 1024 768") +from pandac.PandaModules import TransparencyAttrib + +import direct.directbase.DirectStart +from panda3d.core import * +from direct.showbase.DirectObject import DirectObject +from direct.task import Task +from math import pi, sin, cos, floor, ceil +import platform +import ctypes + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class World(DirectObject): + browser = None + texture = None + nodePath = None + lastMouseMove = (-1, -1) + translateKeys = None + keyModifiers = 0 + modifierKeys = None + + def __init__(self): + environ = loader.loadModel("models/environment") + environ.reparentTo(render) + environ.setScale(0.25,0.25,0.25) + environ.setPos(-8,42,0) + taskMgr.add(self.spinCameraTask, "SpinCameraTask") + + self.texture = Texture() + self.texture.setCompression(Texture.CMOff) + self.texture.setComponentType(Texture.TUnsignedByte) + self.texture.setFormat(Texture.FRgba4) + + cardMaker = CardMaker("browser2d") + cardMaker.setFrame(-0.75, 0.75, -0.75, 0.75) + node = cardMaker.generate() + self.nodePath = render2d.attachNewNode(node) + self.nodePath.setTexture(self.texture) + if TEST_TRANSPARENCY: + self.nodePath.setTransparency(TransparencyAttrib.MAlpha) + self.nodePath.setHpr(0, 0, 5) + + windowHandle = base.win.getWindowHandle().getIntHandle() + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsOffscreen(windowHandle) + if TEST_TRANSPARENCY: + windowInfo.SetTransparentPainting(True) + + # By default window rendering is 30 fps, let's change + # it to 60 for better user experience when scrolling. + browserSettings = {"animation_frame_rate": 60} + + self.browser = cefpython.CreateBrowserSync( + windowInfo, browserSettings, + navigateUrl=GetApplicationPath("cefsimple.html")) + self.browser.SetClientHandler( + ClientHandler(self.browser, self.texture)) + + # SetFocus needs to be called after browser creation. + if platform.system() == "Windows": + ctypes.windll.user32.SetFocus(windowHandle) + self.browser.SendFocusEvent(True) + + self.setBrowserSize() + self.accept("window-event", self.setBrowserSize) + + self.initMouseHandlers() + self.initKeyboardHandlers() + + taskMgr.add(self.messageLoop, "CefMessageLoop") + + def setBrowserSize(self, window=None): + width = int(round(base.win.getXSize() * 0.75)) + height = int(round(base.win.getYSize() * 0.75)) + self.texture.setXSize(width) + self.texture.setYSize(height) + self.browser.SetSize(cefpython.PET_VIEW, width, height) + + def initMouseHandlers(self): + # Browser methods for sending mouse/keyboard/focus events: + # SendKeyEvent(), SendMouseClickEvent(), SendMouseMoveEvent(), + # SendMouseWheelEvent(), SendFocusEvent(), SendCaptureLostEvent(). + + taskMgr.add(self.onMouseMove, "onMouseMove") + self.accept("mouse1", self.onMouseDown) + self.accept("mouse1-up", self.onMouseUp) + self.accept("wheel_up", self.onMouseWheelUp) + self.accept("wheel_down", self.onMouseWheelDown) + + def initKeyboardHandlers(self): + self.translateKeys = { + "f1": cefpython.VK_F1, "f2": cefpython.VK_F2, + "f3": cefpython.VK_F3, "f4": cefpython.VK_F4, + "f5": cefpython.VK_F5, "f6": cefpython.VK_F6, + "f7": cefpython.VK_F7, "f8": cefpython.VK_F8, + "f9": cefpython.VK_F9, "f10": cefpython.VK_F10, + "f11": cefpython.VK_F11, "f12": cefpython.VK_F12, + + "arrow_left": cefpython.VK_LEFT, + "arrow_up": cefpython.VK_UP, + "arrow_down": cefpython.VK_DOWN, + "arrow_right": cefpython.VK_RIGHT, + + "enter": cefpython.VK_RETURN, + "tab": cefpython.VK_TAB, + "space": cefpython.VK_SPACE, + "escape": cefpython.VK_ESCAPE, + "backspace": cefpython.VK_BACK, + "insert": cefpython.VK_INSERT, + "delete": cefpython.VK_DELETE, + "home": cefpython.VK_HOME, + "end": cefpython.VK_END, + "page_up": cefpython.VK_PAGEUP, + "page_down": cefpython.VK_PAGEDOWN, + + "num_lock": cefpython.VK_NUMLOCK, + "caps_lock": cefpython.VK_CAPITAL, + "scroll_lock": cefpython.VK_SCROLL, + + "lshift": cefpython.VK_LSHIFT, + "rshift": cefpython.VK_RSHIFT, + "lcontrol": cefpython.VK_LCONTROL, + "rcontrol": cefpython.VK_RCONTROL, + "lalt": cefpython.VK_LMENU, + "ralt": cefpython.VK_RMENU, + } + + base.buttonThrowers[0].node().setKeystrokeEvent('keystroke') + base.buttonThrowers[0].node().setButtonDownEvent('button-down') + base.buttonThrowers[0].node().setButtonUpEvent('button-up') + base.buttonThrowers[0].node().setButtonRepeatEvent('button-repeat') + + self.accept("keystroke", self.onKeystroke) + self.accept("button-down", self.onButtonDown) + self.accept("button-up", self.onButtonUp) + self.accept("button-repeat", self.onButtonDown) + + self.keyModifiers = 0 + self.modifierKeys = { + "shift": cefpython.KEY_SHIFT, + "ctrl": cefpython.KEY_CTRL, + "alt": cefpython.KEY_ALT + } + + def keyInfo(self, key): + if platform.system() == "Windows": + return (key, 0, 0) + elif platform.system() == "Darwin": + return (key, 0, 0) + elif platform.system() == "Linux": + return (key,) + + def onKeystroke(self, key): + self.browser.SendKeyEvent(cefpython.KEYTYPE_CHAR, + self.keyInfo(ord(key)), 0) + + def onButtonDownOrUp(self, keyType, key): + if key in self.modifierKeys: + self.keyModifiers |= self.modifierKeys[key] + else: + if key in self.translateKeys: + self.browser.SendKeyEvent(keyType, + self.keyInfo(self.translateKeys[key]), + self.keyModifiers) + + def onButtonDown(self, key): + self.onButtonDownOrUp(cefpython.KEYTYPE_KEYDOWN, key) + + def onButtonUp(self, key): + self.onButtonDownOrUp(cefpython.KEYTYPE_KEYUP, key) + + def isMouseInsideBrowser(self, mouse): + if mouse.getX() >= -0.75 and mouse.getX() <= 0.75 and ( + mouse.getY() >= -0.75 and mouse.getY() <= 0.75): + return True + else: + return False + + def getMousePixelCoordinates(self, mouse): + # This calculation works only for the browser area. + relX = mouse.getX() + relY = mouse.getY() + relX += 0.75 # 0 .. 1.5 + relY += 0.75 # 0 .. 1.5 + width = self.texture.getXSize() + height = self.texture.getYSize() + width /= 1.5 + height /= 1.5 + pixelX = relX * width + pixelY = relY * height + pixelY = abs(pixelY - self.texture.getYSize()) + pixelX = int(round(pixelX)) + pixelY = int(round(pixelY)) + return (pixelX, pixelY) + + def onMouseMove(self, task): + if base.mouseWatcherNode.hasMouse(): + mouse = base.mouseWatcherNode.getMouse() + + (lastX, lastY) = self.lastMouseMove + if lastX == mouse.getX() and lastY == mouse.getY(): + return Task.cont + else: + self.lastMouseMove = (mouse.getX(), mouse.getY()) + + if self.isMouseInsideBrowser(mouse): + self.nodePath.setHpr(0, 0, 0) + (x,y) = self.getMousePixelCoordinates(mouse) + self.browser.SendMouseMoveEvent(x, y, mouseLeave=False) + else: + self.browser.SendMouseMoveEvent(-1, -1, mouseLeave=True) + self.nodePath.setHpr(0, 0, 5) + else: + self.nodePath.setHpr(0, 0, 5) + return Task.cont + + def onMouseDown(self): + mouse = base.mouseWatcherNode.getMouse() + (x,y) = self.getMousePixelCoordinates(mouse) + self.browser.SendMouseClickEvent(x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=False, clickCount=1) + + def onMouseUp(self): + mouse = base.mouseWatcherNode.getMouse() + (x,y) = self.getMousePixelCoordinates(mouse) + self.browser.SendMouseClickEvent(x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=True, clickCount=1) + + def onMouseWheelUp(self): + if base.mouseWatcherNode.hasMouse(): + mouse = base.mouseWatcherNode.getMouse() + if self.isMouseInsideBrowser(mouse): + (x,y) = self.getMousePixelCoordinates(mouse) + self.browser.SendMouseWheelEvent(x, y, deltaX=0, deltaY=120) + + def onMouseWheelDown(self): + if base.mouseWatcherNode.hasMouse(): + mouse = base.mouseWatcherNode.getMouse() + if self.isMouseInsideBrowser(mouse): + (x,y) = self.getMousePixelCoordinates(mouse) + self.browser.SendMouseWheelEvent(x, y, deltaX=0, deltaY=-120) + + def messageLoop(self, task): + cefpython.MessageLoopWork() + return Task.cont + + def spinCameraTask(self, task): + angleDegrees = task.time * 6.0 + angleRadians = angleDegrees * (pi / 180.0) + camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) + camera.setHpr(angleDegrees, 0, 0) + return Task.cont + +class ClientHandler: + browser = None + texture = None + + def __init__(self, browser, texture): + self.browser = browser + self.texture = texture + + def OnPaint(self, browser, paintElementType, dirtyRects, buffer): + (width, height) = self.browser.GetSize(paintElementType) + img = self.texture.modifyRamImage() + if paintElementType == cefpython.PET_POPUP: + print("width=%s, height=%s" % (width, height)) + elif paintElementType == cefpython.PET_VIEW: + img.setData(buffer.GetString(mode="bgra", origin="bottom-left")) + else: + raise Exception("Unknown paintElementType: %s" % paintElementType) + + def GetViewRect(self, browser, rect): + return False + print("GetViewRect()") + width = self.texture.getXSize() + height = self.texture.getYSize() + rect.append(0) + rect.append(0) + rect.append(width) + rect.append(height) + return True + + def GetScreenRect(self, browser, rect): + return False + print("GetScreenRect()") + return self.GetViewRect(browser, rect) + + def GetScreenPoint(self, browser, viewX, viewY, screenCoordinates): + return False + print("GetScreenPoint()") + return False + + def OnLoadEnd(self, browser, frame, httpStatusCode): + return + self._saveImage() + + def _saveImage(self): + try: + from PIL import Image + except: + print("PIL library not available, can't save image") + return + (width, height) = self.browser.GetSize(cefpython.PET_VIEW) + buffer = self.browser.GetImage(cefpython.PET_VIEW, width, height) + image = Image.fromstring( + "RGBA", (width,height), + buffer.GetString(mode="rgba", origin="top-left"), + "raw", "RGBA", 0, 1) + image.save("panda3d_image.png", "PNG") + +if __name__ == "__main__": + sys.excepthook = ExceptHook + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + + print("Panda3D version: %s" % PandaSystem.getVersionString()) + w = World() + run() + del w + + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/binaries/pygtk_.py b/cefpython/cef1/windows/binaries/pygtk_.py new file mode 100644 index 00000000..230aec09 --- /dev/null +++ b/cefpython/cef1/windows/binaries/pygtk_.py @@ -0,0 +1,193 @@ +# An example of embedding CEF in PyGTK application. + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + + def __init__(self): + + gobject.timeout_add(10, self.OnTimer) + + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=600, height=400) + self.mainWindow.set_title('PyGTK CEF example') + self.mainWindow.realize() + + self.container = gtk.DrawingArea() + self.container.set_property('can-focus', True) + self.container.connect('size-allocate', self.OnSize) + self.container.show() + + self.searchEntry = gtk.Entry() + # By default, clicking a GTK widget doesn't grab the focus away from a native Win32 control (browser). + self.searchEntry.connect('button-press-event', self.OnWidgetClick) + self.searchEntry.show() + + table = gtk.Table(3, 1, homogeneous=False) + self.mainWindow.add(table) + table.attach(self.CreateMenu(), 0, 1, 0, 1, yoptions=gtk.SHRINK) + table.attach(self.searchEntry, 0, 1, 1, 2, yoptions=gtk.SHRINK) + table.attach(self.container, 0, 1, 2, 3) + table.show() + + windowID = self.container.get_window().handle + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + + self.mainWindow.show() + + # Browser took focus, we need to get it back and give to searchEntry. + self.mainWindow.get_window().focus() + self.searchEntry.grab_focus() + + def CreateMenu(self): + + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + + about = gtk.MenuItem('About') + about.show() + + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + + return menubar + + def OnWidgetClick(self, widget, data): + + self.mainWindow.get_window().focus() + + def OnTimer(self): + + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + + # This function is currently not called by any of code, but if you would like + # for browser to have automatic focus add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + cefpython.WindowUtils.OnSetFocus(self.container.get_window().handle, 0, 0, 0) + + def OnSize(self, widget, sizeAlloc): + + cefpython.WindowUtils.OnSize(self.container.get_window().handle, 0, 0, 0) + + def OnExit(self, widget, data=None): + + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + + version = '.'.join(map(str, list(gtk.gtk_version))) + print('GTK version: %s' % version) + + sys.excepthook = ExceptHook + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + + gobject.threads_init() # timer for messageloop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/binaries/pyqt.py b/cefpython/cef1/windows/binaries/pyqt.py new file mode 100644 index 00000000..c74a6f4e --- /dev/null +++ b/cefpython/cef1/windows/binaries/pyqt.py @@ -0,0 +1,167 @@ +# An example of embedding CEF Python in PyQt4 application. + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +from PyQt4 import QtGui +from PyQt4 import QtCore + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(600, 480) + self.setWindowTitle('PyQT example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winId()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winId())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + self.show() + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("PyQt version: %s" % QtCore.PYQT_VERSION_STR) + print("QtCore version: %s" % QtCore.qVersion()) + + sys.excepthook = ExceptHook + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/binaries/pyside.py b/cefpython/cef1/windows/binaries/pyside.py new file mode 100644 index 00000000..35cc8a8f --- /dev/null +++ b/cefpython/cef1/windows/binaries/pyside.py @@ -0,0 +1,184 @@ +# An example of embedding CEF Python in PySide application. + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import PySide +from PySide import QtGui +from PySide import QtCore +import ctypes + +def GetApplicationPath(file=None): + import re, os + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(600, 480) + self.setWindowTitle('PySide example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winIdFixed()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winIdFixed())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("cefsimple.html")) + self.show() + + def winIdFixed(self): + # PySide bug: QWidget.winId() returns , + # there is no easy way to convert it to int. + try: + return int(self.winId()) + except: + if sys.version_info[0] == 2: + ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p + ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCObject_AsVoidPtr(self.winId()) + elif sys.version_info[0] == 3: + ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p + ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCapsule_GetPointer(self.winId(), None) + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("PySide version: %s" % PySide.__version__) + print("QtCore version: %s" % QtCore.__version__) + + sys.excepthook = ExceptHook + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/binaries/wxpython.html b/cefpython/cef1/windows/binaries/wxpython.html new file mode 100644 index 00000000..ff674443 --- /dev/null +++ b/cefpython/cef1/windows/binaries/wxpython.html @@ -0,0 +1,172 @@ + + + + + CefSimple (utf-8: ąś) + + + + +Use mouse context menu to go Back/Forward in history navigation. + + + +

Google Search

+http://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('wxpython.html') + + + + +

RequestHandler tests

+ +

See messages in the console.

+ +OnBeforeBrowse() - navigate to see message: +wxpython.html +

+ +OnBeforeBrowse() / OnBeforeResourceLoad() - test request.GetPostData() +and request.SetPostData(): +submit a form: + + https://accounts.google.com/ServiceLogin, +upload a file: + + http://encodable.com/uploaddemo/ +

+ +OnBeforeResourceLoad() - try loading nonexistent css file locally: + + LoadCssFile('nonexistent.css') + +

+ +OnBeforeResourceLoad() - try replacing a resource on the fly: + + LoadCssFile('replace-on-the-fly.css') +(css content: body { color: red; }) +

+ +OnResourceRedirect() - try loading this url: + + http://tinyurl.com/google404redirect +

+ +OnResourceResponse() - try loading nonexistent css file via http: + + LoadCssFile('http://www.google.com/404.css') +

+ +OnResourceResponse() - try filtering content of the resource: + + LoadCssFile('content-filter/replace-on-the-fly.css') +(new css content: body { color: green; } and body h3 { color: orange; } ) +

+ + + + + +

WebRequest test

+ +See the console for messages.
+ + + external.WebRequest('https://code.google.com/robots.txt') + +

Frame.CallFunction() test

+ + + + external.DoCallFunction() + + + + +

Cookie tests

+ +See messages in the console. +

+ +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. Visit + + http://www.html-kit.com/tools/cookietester/ and set some cookie, +then go back to this page using the context menu and open a + + new popup window, the cookie should not appear in the popup browser window. +

+ +CookieManager.VisitAllCookies() - visit all cookies: +external.VisitAllCookies() +(note: visit some http:// webpage first, otherwise cookie manager is not +yet created) +

+ +CookieManager.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +- visit a subset of cookies given the url, test: +external.VisitUrlCookies() +

+ +CookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + {name:"Created_Via_Python", value:"yeah really"}) - create the cookie: + external.SetCookie() +

+ +CookieManager.DeleteCookies() - delete the single cookie previously created +via SetCookie(): + external.DeleteCookies() +

+ + + + +

DragHandler test

+ +Try dragging a file, or a text/html fragment to the browser window +and look for the messages in the console. In the wxpython.py script see +ClientHandler.OnDragStart() and OnDragEnter(). + + + + +

DownloadHandler test

+ +Try downloading this file (838 KiB):
+ + http://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip +
+See messages in the console. +The file will be saved in the ./downloads/ directory. + + + + + + diff --git a/cefpython/cef1/windows/binaries/wxpython.py b/cefpython/cef1/windows/binaries/wxpython.py new file mode 100644 index 00000000..bb4fee5e --- /dev/null +++ b/cefpython/cef1/windows/binaries/wxpython.py @@ -0,0 +1,526 @@ +# An example of embedding CEF in wxPython application. + +import platform +if platform.architecture()[0] != "32bit": + raise Exception("Only 32bit architecture is supported") + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import the local module. + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + elif 0x03000000 <= sys.hexversion < 0x04000000: + import cefpython_py32 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import the package. + from cefpython1 import cefpython + +import wx +import time +import re +import uuid + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# From the tests it seems that Flash content behaves +# better when using a timer. +USE_EVT_IDLE = True + +def GetApplicationPath(file=None): + import re, os, platform + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + path = path + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython example', size=(800,600)) + self.CreateMenu() + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.GetHandle()) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("wxpython.html")) + + self.browser.SetClientHandler(ClientHandler()) + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=False) + jsBindings.SetObject("external", JavascriptBindings(self.browser)) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnSetFocus(self, event): + cefpython.WindowUtils.OnSetFocus(self.GetHandle(), 0, 0, 0) + + def OnSize(self, event): + cefpython.WindowUtils.OnSize(self.GetHandle(), 0, 0, 0) + + def OnClose(self, event): + self.browser.CloseBrowser() + self.Destroy() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +class JavascriptBindings: + mainBrowser = None + webRequest = None + webRequestId = 0 + cookieVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def WebRequest(self, url): + request = cefpython.Request.CreateRequest() + request.SetUrl(url) + webRequestClient = WebRequestClient() + # Must keep the reference otherwise WebRequestClient + # callbacks won't be called. + self.webRequest = cefpython.WebRequest.CreateWebRequest(request, + webRequestClient) + + def DoCallFunction(self): + self.mainBrowser.GetMainFrame().CallFunction( + "MyFunction", "abc", 12, [1,2,3], {"qwe": 456, "rty": 789}) + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\nCookie created! Visit html-kit cookietester to see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\nCookie manager not yet created! Visit http website first") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\nCookie deleted! Visit html-kit cookietester to see the result") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\nCookieVisitor.Visit(): total cookies: %s" % total) + print("\nCookieVisitor.Visit(): cookie:") + print(cookie.Get()) + # True to continue visiting cookies + return True + +class WebRequestClient: + def OnStateChange(self, webRequest, state): + stateName = "unknown" + for key, value in cefpython.WebRequest.State.iteritems(): + if value == state: + stateName = key + print("\nWebRequestClient::OnStateChange(): state = %s" % stateName) + + def OnRedirect(self, webRequest, request, response): + print("\nWebRequestClient::OnRedirect(): url = %s" % ( + request.GetUrl()[:80])) + + def OnHeadersReceived(self, webRequest, response): + print("\nWebRequestClient::OnHeadersReceived(): headers = %s" % ( + response.GetHeaderMap())) + + def OnProgress(self, webRequest, bytesSent, totalBytesToBeSent): + print("\nWebRequestClient::OnProgress(): bytesSent = %s, " + "totalBytesToBeSent = %s" % (bytesSent, totalBytesToBeSent)) + + def OnData(self, webRequest, data): + print("\nWebRequestClient::OnData(): data:") + print("-" * 60) + print(data) + print("-" * 60) + + def OnError(self, webRequest, errorCode): + print("\nWebRequestClient::OnError(): errorCode = %s" % errorCode) + +class ContentFilterHandler: + def OnData(self, data, substitute_data): + if data == "body { color: red; }": + substitute_data.SetData("body { color: green; }") + + def OnDrain(self, remainder): + remainder.SetData("body h3 { color: orange; }") + +class ClientHandler: + # -------------------------------------------------------------------------- + # RequestHandler + # -------------------------------------------------------------------------- + contentFilter = None + + def OnBeforeBrowse(self, browser, frame, request, navType, isRedirect): + # - frame.GetUrl() returns current url + # - request.GetUrl() returns new url + # - Return true to cancel the navigation or false to allow + # the navigation to proceed. + # - Modifying headers or post data can be done only in + # OnBeforeResourceLoad() + print("\nOnBeforeBrowse(): request.GetUrl() = %s, " + "request.GetHeaderMap(): %s" % ( + request.GetUrl()[:80], request.GetHeaderMap())) + if request.GetMethod() == "POST": + print("\nOnBeforeBrowse(): POST data: %s" % ( + request.GetPostData())) + + def OnBeforeResourceLoad(self, browser, request, redirectUrl, + streamReader, response, loadFlags): + print("\nOnBeforeResourceLoad(): request.GetUrl() = %s" % ( + request.GetUrl()[:80])) + if request.GetMethod() == "POST": + if request.GetUrl().startswith( + "https://accounts.google.com/ServiceLogin"): + postData = request.GetPostData() + postData["Email"] = "--changed via python" + request.SetPostData(postData) + print("\nOnBeforeResourceLoad(): modified POST data: %s" % ( + request.GetPostData())) + if request.GetUrl().endswith("replace-on-the-fly.css"): + print("\nOnBeforeResourceLoad(): replacing css on the fly") + response.SetStatus(200) + response.SetStatusText("OK") + response.SetMimeType("text/css") + streamReader.SetData("body { color: red; }") + + def OnResourceRedirect(self, browser, oldUrl, newUrl): + print("\nOnResourceRedirect(): oldUrl: %s, newUrl: %s" % ( + oldUrl, newUrl[0])) + + def OnResourceResponse(self, browser, url, response, contentFilter): + print("\nOnResourceResponse(): url = %s, headers = %s" % ( + url[:80], response.GetHeaderMap())) + if url.endswith("content-filter/replace-on-the-fly.css"): + print("\nOnResourceResponse(): setting contentFilter handler") + contentFilter.SetHandler(ContentFilterHandler()) + # Must keep the reference to contentFilter otherwise + # ContentFilterHandler callbacks won't be called. + self.contentFilter = contentFilter + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + cookieManager = cefpython.CookieManager.CreateManager("") + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + # -------------------------------------------------------------------------- + # DragHandler + # -------------------------------------------------------------------------- + + def OnDragStart(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragStart(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + if platform.system() == "Windows": + # Return true to cancel the drag event. + return True + else: + return False + + def OnDragEnter(self, browser, dragData, mask): + maskNames = "" + for key, value in cefpython.Drag.Operation.iteritems(): + if value and (value & mask) == value: + maskNames += " "+key + print("\nOnDragEnter(): mask=%s" % maskNames) + print(" IsLink(): %s" % dragData.IsLink()) + print(" IsFragment(): %s" % dragData.IsFragment()) + print(" IsFile(): %s" % dragData.IsFile()) + print(" GetLinkUrl(): %s" % dragData.GetLinkUrl()) + print(" GetLinkTitle(): %s" % dragData.GetLinkTitle()) + print(" GetLinkMetadata(): %s" % dragData.GetLinkMetadata()) + print(" GetFragmentText(): %s" % dragData.GetFragmentText()) + print(" GetFragmentHtml(): %s" % dragData.GetFragmentHtml()) + print(" GetFragmentBaseUrl(): %s" % dragData.GetFragmentBaseUrl()) + print(" GetFile(): %s" % dragData.GetFile()) + print(" GetFiles(): %s" % dragData.GetFiles()) + # Returning True on Linux causes segmentation fault, + # reported the bug here: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10693 + # Not being able to cancel a drag event is a problem + # only when a link or a folder is dragged, as this will + # cause loading the link or the folder in the browser window. + # When dragging text/html or a file it is not a problem, as + # it does not lead to browser navigating. + if platform.system() == "Windows": + # Return true to cancel the drag event. + return True + else: + return False + + # -------------------------------------------------------------------------- + # DownloadHandler + # -------------------------------------------------------------------------- + + downloadHandler = None + + def GetDownloadHandler(self, browser, mimeType, filename, contentLength): + # Close the browser window if it is a popup with + # no other document contents. + if browser.IsPopup() and not browser.HasDocument(): + browser.CloseBrowser() + # The reference to DownloadHandler must be kept alive + # while download proceeds. + if self.downloadHandler and self.downloadHandler.downloading: + print("\nDownload is already in progress") + return False + self.downloadHandler = DownloadHandler(mimeType, filename, + contentLength) + return self.downloadHandler + +class DownloadHandler: + mimeType = "" + filename = "" + contentLength = -1 # -1 means that file size was not provided. + fp = None + downloadsDir = "./downloads" + alreadyDownloaded = 0 + downloading = False + + def __init__(self, mimeType, filename, contentLength): + self.downloading = True + if not os.path.exists(self.downloadsDir): + os.mkdir(self.downloadsDir) + filename = filename.strip() + if not len(filename): + filename = self.GetUniqueFilename() + filename = self.GetSafeFilename(filename) + print("\nDownloadHandler() created") + print("mimeType: %s" % mimeType) + print("filename: %s" % filename) + print("contentLength: %s" % contentLength) + # Append ".downloading" to the filename, in OnComplete() + # when download finishes get rid of this extension. + filename += ".downloading" + if os.path.exists(self.downloadsDir+"/"+filename): + # If the last download did not succeed, the + # "xxx.downloading" might still be there. + os.remove(self.downloadsDir+"/"+filename) + self.mimeType = mimeType + self.filename = filename + self.contentLength = contentLength + self.fp = open(self.downloadsDir+"/"+filename, "wb") + + def GetSafeFilename(self, filename): + # TODO: + # - remove any unsafe characters (".." or "/" or "\" and + # others), the safest way is to have a regexp with a list + # safe characters. The dots ".." is a special case that + # needs to be treated separately. + if os.path.exists(self.downloadsDir+"/"+filename): + filename = self.GetUniqueFilename()[:4]+"_"+filename + assert not os.path.exists(self.downloadsDir+"/"+filename), ( + "File aready exists") + return filename + + def GetUniqueFilename(self): + # The filename may be empty, in that case generate + # an unique name. + # TODO: + # - guess the extension using the mimeType (but mimeType + # may also be empty), "text/css" => ".css". + return str(uuid.uuid4()).replace("-", "")[:16] + + def OnData(self, data): + # TODO: display progress in percentage or/and KiB/MiB. + if self.alreadyDownloaded == 0: + sys.stdout.write("Download progress: ") + sys.stdout.write(".") + sys.stdout.flush() + self.alreadyDownloaded += len(data) + self.fp.write(data) + # time.sleep(1) # Let's make the progress a bit slower (if cached) + # Return True to continue receiving data, False to cancel. + return True + + def OnComplete(self): + sys.stdout.write("\n") + sys.stdout.flush() + self.fp.close() + currentFile = self.downloadsDir+"/"+self.filename + newFilename = re.sub(".downloading$", "", self.filename) + os.rename(self.downloadsDir+"/"+self.filename, + self.downloadsDir+"/"+newFilename) + self.downloading = False + print("\nDownload complete!") + print("Total downloaded: %s" % self.PrettyBytes( + self.alreadyDownloaded)) + print("See the 'downloads' directory.") + + def PrettyBytes(self, bytes): + KiB = 1024 + return "%.3g KiB" % (bytes / KiB) + +class MyApp(wx.App): + timer = None + timerID = 1 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +if __name__ == '__main__': + sys.excepthook = ExceptHook + # cefpython.g_debug = True + # cefpython.g_debugFile = GetApplicationPath("debug.log") + settings = { + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": GetApplicationPath("debug.log"), + "release_dcheck_enabled": True # Enable only when debugging. + } + cefpython.Initialize(settings) + print('wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + cefpython.Shutdown() diff --git a/cefpython/cef1/windows/cefadvanced.bat b/cefpython/cef1/windows/cefadvanced.bat new file mode 100644 index 00000000..7aa66356 --- /dev/null +++ b/cefpython/cef1/windows/cefadvanced.bat @@ -0,0 +1 @@ +start binaries\cefadvanced.py \ No newline at end of file diff --git a/cefpython/cef1/windows/cefpython.pyd.manifest b/cefpython/cef1/windows/cefpython.pyd.manifest new file mode 100644 index 00000000..72569471 --- /dev/null +++ b/cefpython/cef1/windows/cefpython.pyd.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cefpython/cef1/windows/compile.bat b/cefpython/cef1/windows/compile.bat new file mode 100644 index 00000000..9f0733c6 --- /dev/null +++ b/cefpython/cef1/windows/compile.bat @@ -0,0 +1,50 @@ +for /f %%i in ('python -c "import sys; print(str(sys.version_info[0])+str(sys.version_info[1]));"') do set PYVERSION=%%i + +del "binaries\cefpython_py%PYVERSION%.pyd" +del "setup\cefpython_py%PYVERSION%.pyd" + +for /R %~dp0setup\ %%f in (*.pyx) do @del "%%f" + +rmdir /S /Q "%dp0setup\build\" + +cd "setup" + +call python "fix_includes.py" + +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +call python "setup.py" build_ext --inplace + +REM -- the setup above has disabled ECHO for commands, turning it back on. +ECHO ON + +@if %ERRORLEVEL% neq 0 for /R %~dp0setup\ %%f in (*.pyx) do @del "%%f" +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +for /R %~dp0setup\ %%f in (*.pyx) do @del "%%f" + +rmdir /S /Q "build\" +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +call "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\mt.exe" -nologo -manifest %~dp0\cefpython.pyd.manifest -outputresource:%~dp0\setup\cefpython_py%PYVERSION%.pyd;2 + +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +move "cefpython_py%PYVERSION%.pyd" "../binaries/cefpython_py%PYVERSION%.pyd" +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +copy %~dp0..\..\cef1_api.py %~dp0binaries\cefpython_py%PYVERSION%.py +@if %ERRORLEVEL% neq 0 pause +@if %ERRORLEVEL% neq 0 exit + +cd .. +cd binaries + +call python "cefadvanced.py" + +pause \ No newline at end of file diff --git a/cefpython/cef1/windows/installer/__init__.py.template b/cefpython/cef1/windows/installer/__init__.py.template new file mode 100644 index 00000000..1777ca24 --- /dev/null +++ b/cefpython/cef1/windows/installer/__init__.py.template @@ -0,0 +1,11 @@ +import sys + +if 0x02070000 <= sys.hexversion < 0x03000000: + from . import cefpython_py27 as cefpython +elif 0x03000000 <= sys.hexversion < 0x04000000: + from . import cefpython_py32 as cefpython +else: + raise Exception("Unsupported python version: " + sys.version) + +__version__ = "%(APP_VERSION)s" +__author__ = "The CEF Python authors" diff --git a/cefpython/cef1/windows/installer/innosetup.template b/cefpython/cef1/windows/installer/innosetup.template new file mode 100644 index 00000000..1189c01b --- /dev/null +++ b/cefpython/cef1/windows/installer/innosetup.template @@ -0,0 +1,181 @@ +; Parts of this code was taken from wxPython/distrib/make_installer.py + +[Setup] + +AppName = CEF Python 1 for Python %(PYTHON_VERSION)s +AppVersion = %(APP_VERSION)s +AppVerName = CEF Python 1 version %(APP_VERSION)s for Python %(PYTHON_VERSION)s %(PYTHON_ARCHITECTURE)s + +AppPublisher = Czarek Tomczak +AppPublisherURL = http://code.google.com/cefpython/ +AppSupportURL = https://groups.google.com/group/cefpython?hl=en +AppUpdatesURL = http://code.google.com/cefpython/ +AppCopyright = Copyright 2012-2013 Czarek Tomczak + +DefaultDirName = {code:GetInstallDir|c:\Python} + +DefaultGroupName = CEF Python 1 for Python %(PYTHON_VERSION)s +PrivilegesRequired = none +DisableStartupPrompt = yes +Compression = zip +DirExistsWarning = no +DisableReadyMemo = yes +DisableReadyPage = yes +DisableDirPage = no +DisableProgramGroupPage = no +UsePreviousAppDir = yes +UsePreviousGroup = yes + +SourceDir = %(BINARIES_DIR)s +OutputDir = %(INSTALLER_DIR)s\Output +OutputBaseFilename = %(PACKAGE_NAME)s-%(APP_VERSION)s-win32-py%(PYTHON_VERSION_NODOT)s + +UninstallFilesDir = {app}\%(PACKAGE_NAME)s +LicenseFile = %(BINARIES_DIR)s\LICENSE.txt + +[Icons] + +Name: "{group}\Examples"; Filename: "{app}\%(PACKAGE_NAME)s\examples"; +Name: "{group}\Uninstall Package"; Filename: "{uninstallexe}"; + +[Run] + +Filename: "{app}\%(PACKAGE_NAME)s\examples"; Flags: postinstall shellexec; + +[Files] + +Source: "*.dll"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "locales\*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s\locales"; Flags: ignoreversion; + +Source: "%(INSTALLER_DIR)s\__init__.py.generated"; DestDir: "{app}\%(PACKAGE_NAME)s"; DestName: "__init__.py"; Flags: ignoreversion; + +Source: "cefclient.exe"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +Source: "cefpython_py%(PYTHON_VERSION_NODOT)s.pyd"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "cefpython_py%(PYTHON_VERSION_NODOT)s.py"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +Source: "LICENSE.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +Source: "Microsoft.VC90.CRT.manifest"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +Source: "README.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; wx subpackage +; ------------------------------------------------------------------------------ + +Source: "%(WX_SUBPACKAGE_DIR)s\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\*.txt"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\images\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\wx\images"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; wx examples +; ------------------------------------------------------------------------------ + +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; examples +; ------------------------------------------------------------------------------ + +Source: "*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +Source: "cefadvanced.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "cefsimple.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "cefwindow.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +Source: "cefwxpanel.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "cefwxpanel_sample1.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "cefwxpanel_sample2.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +Source: "icon.ico"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +Source: "panda3d_.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "pygtk_.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "pyqt.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "pyside.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "wxpython.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +[UninstallDelete] + +Type: files; Name: "{app}\%(PACKAGE_NAME)s\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.log"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.log"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.log"; + +[Code] + +program Setup; +var + PythonDir : String; + InstallDir : String; + +function InitializeSetup(): Boolean; +begin + + if not RegQueryStringValue(HKEY_CURRENT_USER, + 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, + 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(HKEY_CURRENT_USER, + 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, + 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + MsgBox('No installation of Python %(PYTHON_VERSION)s ' + + 'found in registry.' + #13 + 'Be sure to enter ' + + 'a pathname that places CEF Python 1 on the ' + + 'PYTHONPATH', + mbConfirmation, MB_OK); + PythonDir := 'C:\Python'; + end; + end; + end; + end; + + InstallDir := PythonDir + '\Lib\site-packages'; + Result := True; +end; + +function GetInstallDir(Default: String): String; +begin + Result := InstallDir; +end; + +function UninstallOld(FileName: String): Boolean; +var + ResultCode: Integer; +begin + Result := False; + if FileExists(FileName) then begin + Result := True; + ResultCode := MsgBox('A prior CEF Python 1 installation was found in ' + + 'this directory. It' + #13 + 'is recommended that it be ' + + 'uninstalled first.' + #13#13 + 'Should I do it?', + mbConfirmation, MB_YESNO); + if ResultCode = IDYES then begin + Exec(FileName, '/SILENT', WizardDirValue(), SW_SHOWNORMAL, + ewWaitUntilTerminated, ResultCode); + end; + end; +end; + +function NextButtonClick(CurPage: Integer): Boolean; +begin + Result := True; + if CurPage <> wpSelectDir then Exit; + UninstallOld(WizardDirValue() + '\%(PACKAGE_NAME)s\unins000.exe') +end; diff --git a/cefpython/cef1/windows/installer/make-installer.py b/cefpython/cef1/windows/installer/make-installer.py new file mode 100644 index 00000000..6ad2dc46 --- /dev/null +++ b/cefpython/cef1/windows/installer/make-installer.py @@ -0,0 +1,73 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a Windows package installer. + +import sys +import os +import platform +import argparse +import re + +ISCC = r"c:\Program Files (x86)\Inno Setup 5\ISCC.exe" +if "INNO5" in os.environ: + ISCC = os.environ["INNO5"] + +TEMPLATE_FILE = os.getcwd()+r"\innosetup.template" +ISS_FILE = os.getcwd()+r"\innosetup.generated" + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + vars = {} + vars["PACKAGE_NAME"] = "cefpython1" + vars["APP_VERSION"] = args.version + vars["PYTHON_VERSION"] = (str(sys.version_info.major) + "." + + str(sys.version_info.minor)) + vars["PYTHON_VERSION_NODOT"] = (str(sys.version_info.major) + "" + + str(sys.version_info.minor)) + vars["PYTHON_ARCHITECTURE"] = platform.architecture()[0] + vars["BINARIES_DIR"] = os.path.realpath(os.getcwd()+r"\..\binaries") + vars["PYD_FILE"] = (vars["BINARIES_DIR"]+r"\cefpython_py" + + str(sys.version_info.major) + str(sys.version_info.minor) + + ".pyd") + vars["INSTALLER_DIR"] = os.getcwd() + vars["WX_SUBPACKAGE_DIR"] = os.path.realpath(os.getcwd()+r"\..\.." + "\wx-subpackage") + + print("Reading template: %s" % TEMPLATE_FILE) + + f = open(TEMPLATE_FILE) + template = f.read() + f.close() + + f = open(ISS_FILE, "w") + f.write(template % vars) + f.close() + + print("Saved: %s" % ISS_FILE) + + initPyTemplate = os.getcwd()+r"\__init__.py.template" + initPyInstall = os.getcwd()+r"\__init__.py.generated" + + f = open(initPyTemplate) + initPyTemplateCode = f.read() + f.close() + + f = open(initPyInstall, "w") + f.write(initPyTemplateCode % vars) + f.close() + print("Saved: %s" % initPyInstall) + + iscc_command = '"'+ ISCC + '" ' + ISS_FILE + print("Running ISCC: %s" % iscc_command) + os.system(iscc_command) + +if __name__ == "__main__": + main() diff --git a/cefpython/cef1/windows/setup/.gitignore b/cefpython/cef1/windows/setup/.gitignore new file mode 100644 index 00000000..d4b2c081 --- /dev/null +++ b/cefpython/cef1/windows/setup/.gitignore @@ -0,0 +1,3 @@ +*.cpp +*.pyx + diff --git a/cefpython/cef1/windows/setup/cefpython.h b/cefpython/cef1/windows/setup/cefpython.h new file mode 100644 index 00000000..2c9c8c9f --- /dev/null +++ b/cefpython/cef1/windows/setup/cefpython.h @@ -0,0 +1,71 @@ +#ifndef __PYX_HAVE__cefpython_py27 +#define __PYX_HAVE__cefpython_py27 + + +#ifndef __PYX_HAVE_API__cefpython_py27 + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +__PYX_EXTERN_C DL_IMPORT(bool) CookieVisitor_Visit(int, CefCookie const &, int, int, bool &); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadEnd(CefRefPtr, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadStart(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LoadHandler_OnLoadError(CefRefPtr, CefRefPtr, enum cef_handler_errorcode_t, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnKeyEvent(CefRefPtr, enum cef_handler_keyevent_type_t, int, int, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnStateChange(int, CefRefPtr, enum cef_weburlrequest_state_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnRedirect(int, CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnHeadersReceived(int, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnProgress(int, CefRefPtr, uint64_t, uint64_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnData(int, CefRefPtr, void *, int); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnError(int, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) ContentFilterHandler_ProcessData(int, void const *, int, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(void) ContentFilterHandler_Drain(int, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeBrowse(CefRefPtr, CefRefPtr, CefRefPtr, enum cef_handler_navtype_t, bool); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeResourceLoad(CefRefPtr, CefRefPtr, CefString &, CefRefPtr &, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceRedirect(CefRefPtr, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceResponse(CefRefPtr, CefString &, CefRefPtr, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnProtocolExecution(CefRefPtr, CefString &, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetDownloadHandler(CefRefPtr, CefString const &, CefString const &, int64, CefRefPtr &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr, bool, CefString &, int, CefString &, CefString &, CefString &, CefString &); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetCookieManager(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr, CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnConsoleMessage(CefRefPtr, CefString &, CefString &, int); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnContentsSizeChange(CefRefPtr, CefRefPtr, int, int); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnNavStateChange(CefRefPtr, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnStatusMessage(CefRefPtr, CefString &, enum cef_handler_statustype_t); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnTooltip(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_DoClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnAfterCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_RunModal(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetViewRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenPoint(CefRefPtr, int, int, int &, int &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupShow(CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupSize(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPaint(CefRefPtr, cef_paint_element_type_t, std::vector &, void *); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnCursorChange(CefRefPtr, CefCursorHandle); +__PYX_EXTERN_C DL_IMPORT(bool) DragHandler_OnDragStart(CefRefPtr, CefRefPtr, enum cef_drag_operations_mask_t); +__PYX_EXTERN_C DL_IMPORT(bool) DragHandler_OnDragEnter(CefRefPtr, CefRefPtr, enum cef_drag_operations_mask_t); +__PYX_EXTERN_C DL_IMPORT(bool) DownloadHandler_ReceivedData(int, void *, int); +__PYX_EXTERN_C DL_IMPORT(void) DownloadHandler_Complete(int); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnUncaughtException(CefRefPtr, CefRefPtr, CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) V8FunctionHandler_Execute(CefRefPtr, int, CefString &, CefRefPtr, CefV8ValueList &, CefRefPtr &, CefString &); + +#endif /* !__PYX_HAVE_API__cefpython_py27 */ + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcefpython_py27(void); +#else +PyMODINIT_FUNC PyInit_cefpython_py27(void); +#endif + +#endif /* !__PYX_HAVE__cefpython_py27 */ diff --git a/cefpython/cef1/windows/setup/delete_pyx_files.bat b/cefpython/cef1/windows/setup/delete_pyx_files.bat new file mode 100644 index 00000000..ae1c5fbd --- /dev/null +++ b/cefpython/cef1/windows/setup/delete_pyx_files.bat @@ -0,0 +1,2 @@ +for /R %~dp0 %%f in (*.pyx) do del "%%f" +pause \ No newline at end of file diff --git a/cefpython/cef1/windows/setup/fix_includes.py b/cefpython/cef1/windows/setup/fix_includes.py new file mode 100644 index 00000000..e25922ba --- /dev/null +++ b/cefpython/cef1/windows/setup/fix_includes.py @@ -0,0 +1,109 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# First, it copies all .pyx files from upper directory to setup/. +# Then, fixes repeating of "include" statements in pyx files. + +# Only the mainfile needs to have "include" statements, +# but we're using PyCharm and to get rid of "unresolved references" +# and other errors displayed in pycharm we are adding "include" +# statements in all of the pyx files. + +# I'm not 100% sure how includes work in Cython, but I suspect that +# a few includes of the same file will include the same content more +# than once, it should work, but function and variable definitions are +# duplicated, it is some kind of overhead and it could lead to some +# problems in the future, better to fix it now. + +# It also checks cdef & cpdef functions whether they are not missing "except *", +# it is required to add it when returning non-python type. + +import glob +import os +import re +import shutil +import sys + +def ExceptAllMissing(content): + + # This is not perfect, won't detect C++ custom types, but will find + # the built-in types, templates and pointers. + patterns = [] + patterns.append( + r"\bcp?def\s+" + "((int|short|long|double|char|unsigned|float|double|cpp_bool" + "|cpp_string|cpp_wstring|uint64_t|uintptr_t|void" + "|CefString)\s+)+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A template ends with bracket: CefRefPtr[CefBrowser] + # or a pointer ends with asterisk: CefBrowser* + "[^\s]+[\]*]\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A reference, eg. CefString& + "[^\s]+&\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + + for pattern in patterns: + match = re.search(pattern, content) + if match: break + + if match: + lineNumber = (content.count("\n", 0, match.start()) + 1) + return lineNumber + +print("\n") +mainfile = "cefpython.pyx" + +pyxfiles = glob.glob("../../../*.pyx") +if not len(pyxfiles): + sys.exit(1) +pyxfiles = [file for file in pyxfiles if file.find(mainfile) == -1] +# Now, pyxfiles contains all pyx files except the mainfile (cefpython.pyx), +# we do not fix includes in mainfile. + +# So that this is the right directory we're in. +if os.path.exists("setup"): + print("Wrong directory, we should be inside setup!") + sys.exit(1) + +# Remove old pyx files in setup directory. +oldpyxfiles = glob.glob("./*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +# Copying pyxfiles and reading its contents. + +print("Copying .pyx files to /setup/: %s" % pyxfiles) +shutil.copy("../../../%s" % mainfile, "./%s" % mainfile) +# Rest of the files will be copied in for loop below. + +print("Fixing includes in .pyx files:") +for pyxfile in pyxfiles: + newfile = "./%s" % os.path.basename(pyxfile) + shutil.copy(pyxfile, newfile) + pyxfile = newfile + with open(pyxfile, "r") as pyxfileopened: + content = pyxfileopened.read() + lineNumber = ExceptAllMissing(content) + if lineNumber: + print("WARNING: 'except *' missing in a cdef/cpdef function, " + "in file %s on line %d" % (os.path.basename(pyxfile), lineNumber)) + sys.exit(1) + # Do not remove the newline - so that line numbers are exact with originals. + (content, subs) = re.subn(r"^include[\t ]+[\"'][^\"'\n\r]+[\"'][\t ]*", "", content, flags=re.MULTILINE) + if subs: + print("%s includes removed in: %s" % (subs, os.path.basename(pyxfile))) + # Reading and writing with the same handle using "r+" mode doesn't work, + # you need to seek(0) and write the same amount of bytes that was in the + # file, otherwise old data from the end of file stays. + with open(pyxfile, "w") as pyxfileopened: + pyxfileopened.write(content) + +print("\n") diff --git a/cefpython/cef1/windows/setup/setup.py b/cefpython/cef1/windows/setup/setup.py new file mode 100644 index 00000000..c32d1f46 --- /dev/null +++ b/cefpython/cef1/windows/setup/setup.py @@ -0,0 +1,108 @@ +from distutils.core import setup +# Use "Extension" from Cython.Distutils so that "cython_directives" works. +# from distutils.extension import Extension +from Cython.Distutils import build_ext, Extension +import sys +import platform +from Cython.Compiler import Options + +# Stop on first error, otherwise hundreds of errors appear in the console. +Options.fast_fail = True + +# Written to cython_includes/compile_time_constants.pxi +CEF_VERSION = 1 + +""" +Building libcef_dll_wrapper +--------------------------- + +libcef_dll_wrapper needs to be compiled with /MD, otherwise you get linker errors +of type "already defined". When you try to compile using /MD you may get warnings: + + warning C4275: non dll-interface class 'stdext::exception' used as base for + dll-interface class 'std::bad_typeid' see declaration of 'stdext::exception' + see declaration of 'std::bad_typeid' + +Which results in build errors. To solve it you need to add command line option: + + -D_HAS_EXCEPTIONS=1 + +Enabling C++ exceptions ("/EHsc") is not required. +""" + +# Python version string: "27" or "32". +PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor) + +def CompileTimeConstants(): + + print("Generating: cython_includes/compile_time_constants.pxi") + with open("./../../../cython_includes/compile_time_constants.pxi", "w") as fd: + fd.write('# This file was generated by setup.py\n') + # A way around Python 3.2 bug: UNAME_SYSNAME is not set. + fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0]) + fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION) + fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major) + +CompileTimeConstants() + +ext_modules = [Extension( + + "cefpython_py%s" % PYTHON_VERSION, + ["cefpython.pyx"], + + # Ignore the warning in the console: + # > C:\Python27\lib\distutils\extension.py:133: UserWarning: + # > Unknown Extension options: 'cython_directives' warnings.warn(msg) + cython_directives={ + # Any conversion to unicode must be explicit using .decode(). + "c_string_type": "bytes", + "c_string_encoding": "utf8", + }, + + language='c++', + + include_dirs=[ + r'./../', + r'./../../', + r'./../../../', + r'./../../../cython_includes/', + ], + + library_dirs=[ + r'./', + r"c:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x86/", + r'./../../http_authentication/Release/', + r'./../../v8function_handler/Release_py%s/' % PYTHON_VERSION, + r'./../../client_handler/Release_py%s/' % PYTHON_VERSION, + r'./../../../cpp_utils/Release/cpp_utils.lib', + ], + + libraries=[ + 'libcef', + 'libcef_dll_wrapper', + 'User32', + 'Gdi32', + 'http_authentication', # Build with /MD. + 'v8function_handler_py%s' % PYTHON_VERSION, # Build with /MD. + 'client_handler_py%s' % PYTHON_VERSION # Build with /MD. + ], + + # /EHsc - using STL string, multimap and others that use C++ exceptions. + extra_compile_args=['/EHsc'], + + # '/ignore:4217' - silence warnings: "locally defined symbol _V8FunctionHandler_Execute + # imported in function "public: virtual bool __thiscall V8FunctionHandler::Execute". + # client_handler or other vcprojects include setup/cefpython.h, + # this is a list of functions with "public" statement that is + # accessible from c++. + extra_link_args=['/ignore:4217'], + + # Defining macros: + # define_macros = [("UNICODE","1"), ("_UNICODE","1"), ] +)] + +setup( + name = 'cefpython_py%s' % PYTHON_VERSION, + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules +) diff --git a/cefpython/cef1/windows/stdint.h b/cefpython/cef1/windows/stdint.h new file mode 100644 index 00000000..d02608a5 --- /dev/null +++ b/cefpython/cef1/windows/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/cefpython/cef1/wx-subpackage/README.txt b/cefpython/cef1/wx-subpackage/README.txt new file mode 100644 index 00000000..a58c7f44 --- /dev/null +++ b/cefpython/cef1/wx-subpackage/README.txt @@ -0,0 +1,6 @@ +This is a wxPython subpackage for the cefpython1 package +that provides an easy to use API for the wxPython GUI library. + +Author: Greg Kacy +License: BSD 3-clause + diff --git a/cefpython/cef1/wx-subpackage/__init__.py b/cefpython/cef1/wx-subpackage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cefpython/cef1/wx-subpackage/chromectrl.py b/cefpython/cef1/wx-subpackage/chromectrl.py new file mode 100644 index 00000000..ada24b32 --- /dev/null +++ b/cefpython/cef1/wx-subpackage/chromectrl.py @@ -0,0 +1,314 @@ +# Additional and wx specific layer of abstraction for the cefpython +# __author__ = "Greg Kacy " + +#-------------------------------------------------------------------------------- + +from cefpython1 import cefpython +from cefpython1.wx.utils import ExceptHook +import os, sys, platform +import wx +import wx.lib.buttons as buttons + +#------------------------------------------------------------------------------- + +# Default timer interval when timer used to service CEF message loop +DEFAULT_TIMER_MILLIS = 10 + +#------------------------------------------------------------------------------- + +class NavigationBar(wx.Panel): + def __init__(self, parent, *args, **kwargs): + wx.Panel.__init__(self, parent, *args, **kwargs) + + self.bitmapDir = os.path.join(os.path.dirname( + os.path.abspath(__file__)), "images") + + self._InitComponents() + self._LayoutComponents() + self._InitEventHandlers() + + def _InitComponents(self): + self.backBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Arrow Left.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + self.forwardBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Arrow Right.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + self.reloadBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Button Load.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + + self.url = wx.TextCtrl(self, id=-1, style=0) + + self.historyPopup = wx.Menu() + + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.backBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.forwardBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.reloadBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + + sizer.Add(self.url, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 12) + + self.SetSizer(sizer) + self.Fit() + + def _InitEventHandlers(self): + self.backBtn.Bind(wx.EVT_CONTEXT_MENU, self.OnButtonContext) + + def __del__(self): + self.historyPopup.Destroy() + + def GetBackButton(self): + return self.backBtn + + def GetForwardButton(self): + return self.forwardBtn + + def GetReloadButton(self): + return self.reloadBtn + + def GetUrlCtrl(self): + return self.url + + def InitHistoryPopup(self): + self.historyPopup = wx.Menu() + + def AddToHistory(self, url): + self.historyPopup.Append(-1, url) + + def OnButtonContext(self, event): + self.PopupMenu(self.historyPopup) + + +class ChromeWindow(wx.Window): + """ + Standalone CEF component. The class provides facilites for interacting + with wx message loop + """ + def __init__(self, parent, url="", useTimer=False, + timerMillis=DEFAULT_TIMER_MILLIS, size=(-1, -1), + *args, **kwargs): + wx.Window.__init__(self, parent, id=wx.ID_ANY, size=size, + *args, **kwargs) + # On Linux absolute file urls need to start with "file://" + # otherwise a path of "/home/some" is converted to "http://home/some". + if platform.system() == "Linux": + if url.startswith("/"): + url = "file://" + url + self.url = url + + windowInfo = cefpython.WindowInfo() + if platform.system() == "Windows": + windowInfo.SetAsChild(self.GetHandle()) + elif platform.system() == "Linux": + windowInfo.SetAsChild(self.GetGtkWidget()) + else: + raise Exception("Unsupported OS") + + # TODO: allow for custom browser settings for the ChromeWindow + browserSettings = {} + if platform.system() == "Linux": + # Disable plugins on Linux as Flash will crash the application + # in CEF 1 on Linux, it's a known problem. + if not "plugins_disabled" in browserSettings: + browserSettings["plugins_disabled"] = True + + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings=browserSettings, navigateUrl=url) + + if platform.system() == "Windows": + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + if useTimer: + self.timerID = 1 + self._CreateTimer(timerMillis) + else: + self.Bind(wx.EVT_IDLE, self.OnIdle) + self._useTimer = useTimer + + def __del__(self): + '''cleanup stuff''' + if self._useTimer: + self.timer.Stop() + # Calling Unbind() is unnecessary and will cause problems on Windows 8, see: + # https://groups.google.com/d/topic/cefpython/iXE7e1ekArI/discussion + # | self.Unbind(wx.EVT_IDLE) + self.browser.CloseBrowser() + + def _CreateTimer(self, millis): + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(millis) # + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + """Service CEF message loop when useTimer is True""" + cefpython.MessageLoopWork() + + def OnIdle(self, event): + """Service CEF message loop when useTimer is False""" + cefpython.MessageLoopWork() + event.Skip() + + def OnSetFocus(self, event): + """OS_WIN only.""" + cefpython.WindowUtils.OnSetFocus(self.GetHandle(), 0, 0, 0) + event.Skip() + + def OnSize(self, event): + """OS_WIN only. Handle the the size event""" + cefpython.WindowUtils.OnSize(self.GetHandle(), 0, 0, 0) + event.Skip() + + def GetBrowser(self): + """Returns the CEF's browser object""" + return self.browser + + def LoadUrl(self, url, onLoadStart=None, onLoadEnd=None): + if onLoadStart or onLoadEnd: + self.GetBrowser().SetClientHandler( + CallbackClientHandler(onLoadStart, onLoadEnd)) + self.GetBrowser().GetMainFrame().LoadUrl(url) + + +class ChromeCtrl(wx.Panel): + def __init__(self, parent, url="", useTimer=False, + timerMillis=DEFAULT_TIMER_MILLIS, hasNavBar=True, + *args, **kwargs): + wx.Panel.__init__(self, parent, *args, **kwargs) + + self.chromeWindow = ChromeWindow(self, url=str(url), useTimer=useTimer) + sizer = wx.BoxSizer(wx.VERTICAL) + self.navigationBar = None + if hasNavBar: + self.navigationBar = self.CreateNavigationBar() + sizer.Add(self.navigationBar, 0, wx.EXPAND|wx.ALL, 0) + self._InitEventHandlers() + + sizer.Add(self.chromeWindow, 1, wx.EXPAND, 0) + + self.SetSizer(sizer) + self.Fit() + + ch = DefaultClientHandler(self) + self.SetClientHandler(ch) + if self.navigationBar: + self.UpdateButtonsState() + + def _InitEventHandlers(self): + self.navigationBar.backBtn.Bind(wx.EVT_BUTTON, self.OnLeft) + self.navigationBar.forwardBtn.Bind(wx.EVT_BUTTON, self.OnRight) + self.navigationBar.reloadBtn.Bind(wx.EVT_BUTTON, self.OnReload) + + def GetNavigationBar(self): + return self.navigationBar + + def SetNavigationBar(self, navigationBar): + sizer = self.GetSizer() + if self.navigationBar: + # remove previous one + sizer.Replace(self.navigationBar, navigationBar) + self.navigationBar.Hide() + del self.navigationBar + else: + sizer.Insert(0, navigationBar, 0, wx.EXPAND) + self.navigationBar = navigationBar + sizer.Fit(self) + + def CreateNavigationBar(self): + np = NavigationBar(self) + return np + + def SetClientHandler(self, handler): + self.chromeWindow.GetBrowser().SetClientHandler(handler) + + def OnLeft(self, event): + if self.chromeWindow.GetBrowser().CanGoBack(): + self.chromeWindow.GetBrowser().GoBack() + self.UpdateButtonsState() + + def OnRight(self, event): + if self.chromeWindow.GetBrowser().CanGoForward(): + self.chromeWindow.GetBrowser().GoForward() + self.UpdateButtonsState() + + def OnReload(self, event): + self.chromeWindow.GetBrowser().Reload() + self.UpdateButtonsState() + + def UpdateButtonsState(self): + self.navigationBar.backBtn.Enable( + self.chromeWindow.GetBrowser().CanGoBack()) + self.navigationBar.forwardBtn.Enable( + self.chromeWindow.GetBrowser().CanGoForward()) + + def OnLoadStart(self, browser, frame): + if self.navigationBar: + self.UpdateButtonsState() + self.navigationBar.GetUrlCtrl().SetValue( + browser.GetMainFrame().GetUrl()) + self.navigationBar.AddToHistory(browser.GetMainFrame().GetUrl()) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + pass + +class DefaultClientHandler(object): + def __init__(self, parentCtrl): + self.parentCtrl = parentCtrl + + def OnLoadStart(self, browser, frame): + self.parentCtrl.OnLoadStart(browser, frame) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + self.parentCtrl.OnLoadEnd(browser, frame, httpStatusCode) + + def OnLoadError(self, browser, frame, errorCode, failedUrl, errorText): + # TODO + print("ERROR LOADING URL : %s" % failedUrl) + +class CallbackClientHandler(object): + def __init__(self, onLoadStart=None, onLoadEnd=None): + self.onLoadStart = onLoadStart + self.onLoadEnd = onLoadEnd + + def OnLoadStart(self, browser, frame): + if self.onLoadStart and frame.GetUrl() != "about:blank": + self.onLoadStart(browser, frame) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + if self.onLoadEnd and frame.GetUrl() != "about:blank": + self.onLoadEnd(browser, frame, httpStatusCode) + + def OnLoadError(self, browser, frame, errorCode, failedUrl, errorText): + # TODO + print("ERROR LOADING URL : %s" % failedUrl) + +#------------------------------------------------------------------------------- + +def Initialize(settings=None): + """Initializes CEF, We should do it before initializing wx + If no settings passed a default is used + """ + sys.excepthook = ExceptHook + if not settings: + settings = {} + if not "log_severity" in settings: + settings["log_severity"] = cefpython.LOGSEVERITY_INFO + if not "log_file" in settings: + settings["log_file"] = "" + if platform.system() == "Linux": + # On Linux we need to set locales and resources directories. + if not "locales_dir_path" in settings: + settings["locales_dir_path"] = cefpython.GetModuleDirectory()+( + "/locales") + if not "resources_dir_path" in settings: + settings["resources_dir_path"] = cefpython.GetModuleDirectory() + + cefpython.Initialize(settings) + +def Shutdown(): + """Shuts down CEF, should be called by app exiting code""" + cefpython.Shutdown() diff --git a/cefpython/cef1/wx-subpackage/examples/back.png b/cefpython/cef1/wx-subpackage/examples/back.png new file mode 100644 index 00000000..3e8f12fe Binary files /dev/null and b/cefpython/cef1/wx-subpackage/examples/back.png differ diff --git a/cefpython/cef1/wx-subpackage/examples/forward.png b/cefpython/cef1/wx-subpackage/examples/forward.png new file mode 100644 index 00000000..cfab7cfb Binary files /dev/null and b/cefpython/cef1/wx-subpackage/examples/forward.png differ diff --git a/cefpython/cef1/wx-subpackage/examples/reload_page.png b/cefpython/cef1/wx-subpackage/examples/reload_page.png new file mode 100644 index 00000000..3fa8db76 Binary files /dev/null and b/cefpython/cef1/wx-subpackage/examples/reload_page.png differ diff --git a/cefpython/cef1/wx-subpackage/examples/sample1.html b/cefpython/cef1/wx-subpackage/examples/sample1.html new file mode 100644 index 00000000..dd27ee41 --- /dev/null +++ b/cefpython/cef1/wx-subpackage/examples/sample1.html @@ -0,0 +1,33 @@ + + + + + sample 1 + + + + +sample1.py - wxPython example for the CEF Python framework + +

Google Search

+ + http://www.google.com/ + +

User agent

+ + + +

Popup

+ + + window.open('sample1.html') + +










+










+










+ + + diff --git a/cefpython/cef1/wx-subpackage/examples/sample1.py b/cefpython/cef1/wx-subpackage/examples/sample1.py new file mode 100644 index 00000000..788c514e --- /dev/null +++ b/cefpython/cef1/wx-subpackage/examples/sample1.py @@ -0,0 +1,34 @@ +# Simple sample ilustrating the usage of CEFWindow class +# __author__ = "Greg Kacy " + +import os +import wx +import cefpython1.wx.chromectrl as chrome + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example1', size=(600,400)) + + self.cefWindow = chrome.ChromeWindow(self, + url=os.path.join(os.path.dirname(os.path.abspath(__file__)), + "sample1.html")) + + sizer = wx.BoxSizer() + sizer.Add(self.cefWindow, 1, wx.EXPAND, 0) + self.SetSizer(sizer) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + self.Destroy() + +if __name__ == '__main__': + chrome.Initialize() + print('sample1.py: wx.version=%s' % wx.version()) + app = wx.PySimpleApp() + MainFrame().Show() + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown. + del app + chrome.Shutdown() diff --git a/cefpython/cef1/wx-subpackage/examples/sample2.py b/cefpython/cef1/wx-subpackage/examples/sample2.py new file mode 100644 index 00000000..d6ae5ebf --- /dev/null +++ b/cefpython/cef1/wx-subpackage/examples/sample2.py @@ -0,0 +1,74 @@ +# Slightly more advanced sample illustrating the usage of CEFWindow class +# __author__ = "Greg Kacy " + +import wx +import wx.lib.agw.flatnotebook as fnb +import cefpython1.wx.chromectrl as chrome + +ROOT_NAME = "My Locations" + +URLS = ["http://gmail.com", + "http://maps.google.com", + "http://youtube.com", + "http://yahoo.com", + "http://wikipedia.com", + "http://cyaninc.com", + "http://tavmjong.free.fr/INKSCAPE/MANUAL/web/svg_tests.php" + ] + + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example2', size=(1024, 768)) + + self.initComponents() + self.layoutComponents() + self.initEventHandlers() + + def initComponents(self): + self.tree = wx.TreeCtrl(self, id=-1, size=(200, -1)) + self.root = self.tree.AddRoot(ROOT_NAME) + for url in URLS: + self.tree.AppendItem(self.root, url) + self.tree.Expand(self.root) + + self.tabs = fnb.FlatNotebook(self, wx.ID_ANY, agwStyle=fnb.FNB_NODRAG | fnb.FNB_X_ON_TAB) + + def layoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.tree, 0, wx.EXPAND) + sizer.Add(self.tabs, 1, wx.EXPAND) + self.SetSizer(sizer) + + def initEventHandlers(self): + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree) + self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosing) + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnSelChanged(self, event): + self.item = event.GetItem() + url = self.tree.GetItemText(self.item) + if url and url != ROOT_NAME: + cefPanel = chrome.ChromeCtrl(self.tabs, useTimer=True, url=str(url)) + self.tabs.AddPage(cefPanel, url) + self.tabs.SetSelection(self.tabs.GetPageCount()-1) + event.Skip() + + def OnPageClosing(self, event): + print("sample2.py: One could place some extra closing stuff here") + event.Skip() + + def OnClose(self, event): + self.Destroy() + +if __name__ == '__main__': + chrome.Initialize() + print('sample2.py: wx.version=%s' % wx.version()) + app = wx.PySimpleApp() + MainFrame().Show() + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown. + del app + chrome.Shutdown() + diff --git a/cefpython/cef1/wx-subpackage/examples/sample3.py b/cefpython/cef1/wx-subpackage/examples/sample3.py new file mode 100644 index 00000000..bffa5db7 --- /dev/null +++ b/cefpython/cef1/wx-subpackage/examples/sample3.py @@ -0,0 +1,79 @@ +# Slightly more advanced sample illustrating the usage of CEFWindow class +# __author__ = "Greg Kacy " + +import os +import wx +import wx.lib.agw.flatnotebook as fnb +import cefpython1.wx.chromectrl as chrome + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example3', size=(800,600)) + self._InitComponents() + self._LayoutComponents() + self._InitEventHandlers() + + def _InitComponents(self): + self.tabs = fnb.FlatNotebook(self, wx.ID_ANY, + agwStyle=fnb.FNB_NODRAG|fnb.FNB_X_ON_TAB) + + ctrl1 = chrome.ChromeCtrl(self.tabs, useTimer=True, + url="wikipedia.org") + ctrl1.GetNavigationBar().GetUrlCtrl().SetEditable(False) + ctrl1.GetNavigationBar().GetBackButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "back.png"), wx.BITMAP_TYPE_PNG)) + ctrl1.GetNavigationBar().GetForwardButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "forward.png"), wx.BITMAP_TYPE_PNG)) + ctrl1.GetNavigationBar().GetReloadButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "reload_page.png"), wx.BITMAP_TYPE_PNG)) + + self.tabs.AddPage(ctrl1, "Wikipedia") + + ctrl2 = chrome.ChromeCtrl(self.tabs, useTimer=True, url="google.com", + hasNavBar=False) + self.tabs.AddPage(ctrl2, "Google") + + ctrl3 = chrome.ChromeCtrl(self.tabs, useTimer=True, url="greenpeace.org") + ctrl3.SetNavigationBar(CustomNavigationBar(ctrl3)) + self.tabs.AddPage(ctrl3, "Greenpeace") + + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.tabs, 1, wx.EXPAND) + self.SetSizer(sizer) + + def _InitEventHandlers(self): + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + self.Destroy() + + +class CustomNavigationBar(chrome.NavigationBar): + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.url, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 12) + + sizer.Add(self.GetBackButton(), 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.GetForwardButton(), 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + # in this example we dont want reload button + self.GetReloadButton().Hide() + self.SetSizer(sizer) + self.Fit() + +if __name__ == '__main__': + chrome.Initialize() + print('sample3.py: wx.version=%s' % wx.version()) + app = wx.PySimpleApp() + MainFrame().Show() + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown. + del app + chrome.Shutdown() + diff --git a/cefpython/cef1/wx-subpackage/images/Arrow Left.png b/cefpython/cef1/wx-subpackage/images/Arrow Left.png new file mode 100644 index 00000000..640c707d Binary files /dev/null and b/cefpython/cef1/wx-subpackage/images/Arrow Left.png differ diff --git a/cefpython/cef1/wx-subpackage/images/Arrow Right.png b/cefpython/cef1/wx-subpackage/images/Arrow Right.png new file mode 100644 index 00000000..0321a83e Binary files /dev/null and b/cefpython/cef1/wx-subpackage/images/Arrow Right.png differ diff --git a/cefpython/cef1/wx-subpackage/images/Button Load.png b/cefpython/cef1/wx-subpackage/images/Button Load.png new file mode 100644 index 00000000..b7457a4a Binary files /dev/null and b/cefpython/cef1/wx-subpackage/images/Button Load.png differ diff --git a/cefpython/cef1/wx-subpackage/utils.py b/cefpython/cef1/wx-subpackage/utils.py new file mode 100644 index 00000000..c3a23f46 --- /dev/null +++ b/cefpython/cef1/wx-subpackage/utils.py @@ -0,0 +1,19 @@ +# Additional and wx specific layer of abstraction for the cefpython +# __author__ = "Greg Kacy " + +#------------------------------------------------------------------------------- + +def ExceptHook(excType, excValue, traceObject): + import traceback, os + errorMsg = "\n".join(traceback.format_exception( + excType, excValue, traceObject)) + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding="ascii", errors="replace") + else: + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + #cefpython.QuitMessageLoop() + #cefpython.Shutdown() + # So that "finally" does not execute. + #os._exit(1) diff --git a/cefpython/cef1_api.py b/cefpython/cef1_api.py new file mode 100644 index 00000000..0b0e988c --- /dev/null +++ b/cefpython/cef1_api.py @@ -0,0 +1,815 @@ +# This file contains API for the "cefpython.pyd" module, all functions are dummy. +# Use it as a quick reference. Use it for code completion in your IDE. +# This file does NOT need to be distribitued along with binaries. + +raise Exception("A dummy API file was imported instead of the PYD module.") + +""" +Detailed documentation with examples can be found on wiki pages: +http://code.google.com/p/cefpython/w/list +""" + +# Global functions in cefpython module. + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl): + return Browser() + +def FormatJavascriptStackTrace(stackTrace): + return "" + +def GetBrowserByWindowHandle(windowHandle): + return Browser() + +def GetJavascriptStackTrace(frameLimit=100): + return [] + +def Initialize(applicationSettings={}): + return None + +def IsKeyModifier(key, modifiers): + return False + +def MessageLoop(): + return None + +def MessageLoopWork(): + return None + +def QuitMessageLoop(): + return None + +def Shutdown(): + return None + +def GetModuleDirectory(): + return "" + +# +# Settings +# + +# Values are dummy, these are NOT the defaults. +ApplicationSettings = { + "auto_detect_proxy_settings_enabled": False, + "cache_path": "", + "extra_plugin_paths": [""], + "graphics_implementation": ANGLE_IN_PROCESS, + "javascript_flags": "", + "local_storage_quota": 5*1024*1024, + "locale": "", + "locales_dir_path": "", + "log_file": "", + "log_severity": LOGSEVERITY_INFO, + "release_dcheck_enabled": False, + "multi_threaded_message_loop": False, + "pack_loading_disabled": False, + "product_version": "", + "resources_dir_path": "", + "session_storage_quota": 5*1024*1024, + "string_encoding": "utf-8", + "uncaught_exception_stack_size": 0, + "user_agent": "", +} + +# ApplicationSettings["log_severity"] +LOGSEVERITY_VERBOSE = 0 +LOGSEVERITY_INFO = 0 +LOGSEVERITY_WARNING = 0 +LOGSEVERITY_ERROR = 0 +LOGSEVERITY_ERROR_REPORT = 0 +LOGSEVERITY_DISABLE = 0 + +# ApplicationSettings["graphics_implementation"] +ANGLE_IN_PROCESS = 0 +ANGLE_IN_PROCESS_COMMAND_BUFFER = 0 +DESKTOP_IN_PROCESS = 0 +DESKTOP_IN_PROCESS_COMMAND_BUFFER = 0 + +# Values are dummy, these are NOT the defaults. +BrowserSettings = { + "accelerated_2d_canvas_disabled": False, + "accelerated_compositing_enabled": False, + "accelerated_filters_disabled": False, + "accelerated_layers_disabled": False, + "accelerated_plugins_disabled": False, + "accelerated_video_disabled": False, + "animation_frame_rate": 0, + "application_cache_disabled": False, + "author_and_user_styles_disabled": False, + "caret_browsing_enabled": False, + "cursive_font_family": "", + "databases_disabled": False, + "default_encoding": "iso-8859-1", + "default_fixed_font_size": 0, + "default_font_size": 0, + "developer_tools_disabled": False, + "dom_paste_disabled": False, + "drag_drop_disabled": False, + "encoding_detector_enabled": False, + "fantasy_font_family": "", + "file_access_from_file_urls_allowed": False, + "fixed_font_family": "", + "fullscreen_enabled": False, + "history_disabled": False, + "hyperlink_auditing_disabled": False, + "image_load_disabled": False, + "java_disabled": False, + "javascript_access_clipboard_disallowed": False, + "javascript_close_windows_disallowed": False, + "javascript_disabled": False, + "javascript_open_windows_disallowed": False, + "load_drops_disabled": False, + "local_storage_disabled": False, + "minimum_font_size": 0, + "minimum_logical_font_size": 0, + "page_cache_disabled": False, + "plugins_disabled": False, + "remote_fonts_disabled": False, + "sans_serif_font_family": "", + "serif_font_family": "", + "shrink_standalone_images_to_fit": False, + "site_specific_quirks_disabled": False, + "standard_font_family": "", + "tab_to_links_disabled": False, + "text_area_resize_disabled": False, + "universal_access_from_file_urls_allowed": False, + "user_style_sheet_enabled": False, + "user_style_sheet_location": "", + "web_security_disabled": False, + "webgl_disabled": False, + "xss_auditor_enabled": False, +} + +# +# Browser object. +# + +class Browser: + + def CanGoBack(self): + return False + + def CanGoForward(self): + return False + + def ClearHistory(self): + return None + + def CloseBrowser(self): + return None + + def CloseDevTools(self): + return None + + def Find(self, searchID, searchText, forward, matchCase, findNext): + return None + + def GetClientCallback(self, name): + return callback + + def GetClientCallbacksDict(self): + return {} + + def GetFocusedFrame(self): + return Frame() + + def GetFrame(self): + return Frame() + + def GetFrameNames(self): + return ["", ""] + + def GetIdentifier(self): + return 0 + + def GetImage(self, paintElementType, width, height): + return PaintBuffer() + + def GetJavascriptBindings(self): + return JavascriptBindings() + + def GetMainFrame(self): + return Frame() + + def GetOpenerWindowHandle(self): + return 0 + + def GetOuterWindowHandle(self): + return 0 + + def GetSize(self, paintElementType): + return (0,0,) + + def GetUserData(self, key): + return None + + def GetWindowID(self): + return windowID + + def GetWindowHandle(self): + return 0 + + def GetZoomLevel(self): + return 0.0 + + def GoBack(self): + return None + + def GoForward(self): + return None + + def HasDocument(self): + return False + + def HidePopup(self): + return None + + def Invalidate(self, dirtyRect): + return None + + def IsFullscreen(self): + return False + + def IsPopup(self): + return False + + def IsPopupVisible(self): + return False + + def IsWindowRenderingDisabled(self): + return False + + def Reload(self): + return None + + def ReloadIgnoreCache(self): + return None + + def SendKeyEvent(self, keyType, keyInfo, modifiers): + return None + + def SendMouseClickEvent(self, x, y, mouseButtonType, mouseUp, clickCount): + return None + + def SendMouseMoveEvent(self, x, y, mouseLeave): + return None + + def SendMouseWheelEvent(self, x, y, deltaX, deltaY): + return None + + def SendFocusEvent(self, setFocus): + return None + + def SendCaptureLostEvent(self): + return None + + def SetClientCallback(self, name, callback): + return None + + def SetClientHandler(self, clientHandler): + return None + + def SetFocus(self, enable): + return None + + def SetJavascriptBindings(self, javascriptBindings): + return None + + def SetSize(self, paintElementType, width, height): + return None + + def SetZoomLevel(self, zoomLevel): + return None + + def SetUserData(self, key, value): + return None + + def ShowDevTools(self): + return None + + def StopLoad(self): + return None + + def StopFinding(self, clearSelection): + return None + + def ToggleFullscreen(self): + return None + +# +# Frame object. +# + +class Frame: + + def Copy(self): + return None + + def Cut(self): + return None + + def Delete(self): + return None + + def ExecuteJavascript(self, jsCode, scriptUrl=None, startLine=None): + return None + + def GetIdentifier(self): + return 0 + + def GetName(self): + return "" + + def GetProperty(self, name): + return mixed + + def GetSource(self): + return "" + + def GetText(self): + return "" + + def GetUrl(self): + return "" + + def IsFocused(self): + return False + + def IsMain(self): + return False + + def LoadString(self, value, url): + return None + + def LoadUrl(self, url): + return None + + def Paste(self): + return None + + def Print(self): + return None + + def Redo(self): + return None + + def SelectAll(self): + return None + + def SetProperty(self, name, value): + return None + + def Undo(self): + return None + + def ViewSource(self): + return None + +class Response: + + def GetStatus(self): + return 0 + + def SetStatus(self, status): + return None + + def GetStatusText(self): + return "" + + def SetStatusText(self, statusText): + return None + + def GetMimeType(self): + return "" + + def SetMimeType(self, mimeType): + return None + + def GetHeader(self, name): + return "" + + def GetHeaderMap(self): + return {} + + def GetHeaderMultimap(self): + return [("","")] + + def SetHeaderMap(self, headerMap={}): + return None + + def SetHeaderMultimap(self, headerMultimap=[]): + return None + +class PaintBuffer: + + def GetIntPointer(self): + return 0 + + def GetString(self, mode="bgra", origin="top-left"): + return "" + +class JavascriptBindings: + + def __init__(self, bindToFrames=False, bindToPopups=False): + return None + + def IsValueAllowed(self, value): + return False + + def Rebind(self): + return None + + def SetFunction(self, name, func): + return None + + def SetObject(self, name, obj): + return None + + def SetProperty(self, name, value): + return None + +class JavascriptCallback: + + def Call(self, param1, param2, param3_etc): + return mixed + + def GetName(self): + return name + +class WindowUtils: + + @staticmethod + def OnSetFocus(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnSize(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def OnEraseBackground(windowID, msg, wparam, lparam): + return 0 + + @staticmethod + def SetTitle(pyBrowser, pyTitle): + return None + + @staticmethod + def SetIcon(pyBrowser, icon="inherit"): + return None + +# +# DisplayHandler. +# + +# statusType constants (OnStatusMessage). +STATUSTYPE_TEXT = 0 +STATUSTYPE_MOUSEOVER_URL = 0 +STATUSTYPE_KEYBOARD_FOCUS_URL = 0 + +def DisplayHandler_OnAddressChange(browser, frame, url): + return None + +def DisplayHandler_OnConsoleMessage(browser, message, source, line): + return False + +def DisplayHandler_OnContentsSizeChange(browser, frame, width, height): + return None + +def DisplayHandler_OnNavStateChange(browser, canGoBack, canGoForward): + return None + +def DisplayHandler_OnStatusMessage(browser, text, statusType): + return None + +def DisplayHandler_OnTitleChange(browser, title): + return None + +def DisplayHandler_OnTooltip(browser, text_out=[""]): + return False + +# +# KeyboardHandler. +# + +def KeyboardHandler_OnKeyEvent( + browser, eventType, keyCode, modifiers, isSystemKey, isAfterJavascript): + return False + +# keyCode constants (OnKeyEvent). +VK_0=0x30 +VK_1=0x31 +VK_2=0x32 +VK_3=0x33 +VK_4=0x34 +VK_5=0x35 +VK_6=0x36 +VK_7=0x37 +VK_8=0x38 +VK_9=0x39 +VK_A=0x041 +VK_B=0x042 +VK_C=0x043 +VK_D=0x044 +VK_E=0x045 +VK_F=0x046 +VK_G=0x047 +VK_H=0x048 +VK_I=0x049 +VK_J=0x04A +VK_K=0x04B +VK_L=0x04C +VK_M=0x04D +VK_N=0x04E +VK_O=0x04F +VK_P=0x050 +VK_Q=0x051 +VK_R=0x052 +VK_S=0x053 +VK_T=0x054 +VK_U=0x055 +VK_V=0x056 +VK_W=0x057 +VK_X=0x058 +VK_Y=0x059 +VK_Z=0x05A +VK_F1=0x70 +VK_F2=0x71 +VK_F3=0x72 +VK_F4=0x73 +VK_F5=0x74 +VK_F6=0x75 +VK_F7=0x76 +VK_F8=0x77 +VK_F9=0x78 +VK_F10=0x79 +VK_F11=0x7A +VK_F12=0x7B +VK_F13=0x7C +VK_F14=0x7D +VK_F15=0x7E +VK_F16=0x7F +VK_F17=0x80 +VK_F18=0x81 +VK_F19=0x82 +VK_F20=0x83 +VK_F21=0x84 +VK_F22=0x85 +VK_F23=0x86 +VK_F24=0x87 +VK_LSHIFT=0xA0 +VK_RSHIFT=0xA1 +VK_LCONTROL=0xA2 +VK_RCONTROL=0xA3 +VK_LMENU=0xA4 +VK_RMENU=0xA5 +VK_BACK=0x08 +VK_TAB=0x09 +VK_SPACE=0x20 +VK_PRIOR=0x21 +VK_NEXT=0x22 +VK_END=0x23 +VK_HOME=0x24 +VK_LEFT=0x25 +VK_UP=0x26 +VK_RIGHT=0x27 +VK_DOWN=0x28 +VK_SELECT=0x29 +VK_PRINT=0x2A +VK_EXECUTE=0x2B +VK_SNAPSHOT=0x2C +VK_INSERT=0x2D +VK_DELETE=0x2E +VK_HELP=0x2F +VK_SHIFT=0x10 +VK_CONTROL=0x11 +VK_MENU=0x12 +VK_PAUSE=0x13 +VK_CAPITAL=0x14 +VK_CLEAR=0x0C +VK_RETURN=0x0D +VK_ESCAPE=0x1B +VK_LWIN=0x5B +VK_RWIN=0x5C +VK_APPS=0x5D +VK_SLEEP=0x5F +VK_NUMPAD0=0x60 +VK_NUMPAD1=0x61 +VK_NUMPAD2=0x62 +VK_NUMPAD3=0x63 +VK_NUMPAD4=0x64 +VK_NUMPAD5=0x65 +VK_NUMPAD6=0x66 +VK_NUMPAD7=0x67 +VK_NUMPAD8=0x68 +VK_NUMPAD9=0x69 +VK_BROWSER_BACK=0xA6 +VK_BROWSER_FORWARD=0xA7 +VK_BROWSER_REFRESH=0xA8 +VK_BROWSER_STOP=0xA9 +VK_BROWSER_SEARCH=0xAA +VK_BROWSER_FAVORITES=0xAB +VK_BROWSER_HOME=0xAC +VK_VOLUME_MUTE=0xAD +VK_VOLUME_DOWN=0xAE +VK_VOLUME_UP=0xAF +VK_MEDIA_NEXT_TRACK=0xB0 +VK_MEDIA_PREV_TRACK=0xB1 +VK_MEDIA_STOP=0xB2 +VK_MEDIA_PLAY_PAUSE=0xB3 +VK_LAUNCH_MAIL=0xB4 +VK_LAUNCH_MEDIA_SELECT=0xB5 +VK_LAUNCH_APP1=0xB6 +VK_LAUNCH_APP2=0xB7 +VK_MULTIPLY=0x6A +VK_ADD=0x6B +VK_SEPARATOR=0x6C +VK_SUBTRACT=0x6D +VK_DECIMAL=0x6E +VK_DIVIDE=0x6F +VK_NUMLOCK=0x90 +VK_SCROLL=0x91 +VK_LBUTTON=0x01 +VK_RBUTTON=0x02 +VK_CANCEL=0x03 +VK_MBUTTON=0x04 +VK_XBUTTON1=0x05 +VK_XBUTTON2=0x06 +VK_KANA=0x15 +VK_HANGEUL=0x15 +VK_HANGUL=0x15 +VK_JUNJA=0x17 +VK_FINAL=0x18 +VK_HANJA=0x19 +VK_KANJI=0x19 +VK_CONVERT=0x1C +VK_NONCONVERT=0x1D +VK_ACCEPT=0x1E +VK_MODECHANGE=0x1F +VK_PROCESSKEY=0xE5 +VK_PACKET=0xE7 +VK_ICO_HELP=0xE3 +VK_ICO_00=0xE4 +VK_ICO_CLEAR=0xE6 + +# eventType constants (OnKeyEvent). +KEYEVENT_RAWKEYDOWN = 0 +KEYEVENT_KEYDOWN = 0 +KEYEVENT_KEYUP = 0 +KEYEVENT_CHAR = 0 + +# Constants for checking modifiers param (OnKeyEvent), for use with IsKeyModifier() function. +KEY_NONE = 0 +KEY_SHIFT = 0 +KEY_CTRL = 0 +KEY_ALT = 0 +KEY_META = 0 +KEY_KEYPAD = 0 + +# +# LoadHandler. +# + +def LoadHandler_OnLoadEnd(browser, frame, httpStatusCode): + return None + +def LoadHandler_OnLoadError(browser, frame, errorCode, failedUrl, errorText_out=[""]): + return False + +def LoadHandler_OnLoadStart(browser, frame): + return None + +# errorCode constants (OnLoadError). +ERR_FAILED = 0 +ERR_ABORTED = 0 +ERR_INVALID_ARGUMENT = 0 +ERR_INVALID_HANDLE = 0 +ERR_FILE_NOT_FOUND = 0 +ERR_TIMED_OUT = 0 +ERR_FILE_TOO_BIG = 0 +ERR_UNEXPECTED = 0 +ERR_ACCESS_DENIED = 0 +ERR_NOT_IMPLEMENTED = 0 +ERR_CONNECTION_CLOSED = 0 +ERR_CONNECTION_RESET = 0 +ERR_CONNECTION_REFUSED = 0 +ERR_CONNECTION_ABORTED = 0 +ERR_CONNECTION_FAILED = 0 +ERR_NAME_NOT_RESOLVED = 0 +ERR_INTERNET_DISCONNECTED = 0 +ERR_SSL_PROTOCOL_ERROR = 0 +ERR_ADDRESS_INVALID = 0 +ERR_ADDRESS_UNREACHABLE = 0 +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = 0 +ERR_TUNNEL_CONNECTION_FAILED = 0 +ERR_NO_SSL_VERSIONS_ENABLED = 0 +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = 0 +ERR_SSL_RENEGOTIATION_REQUESTED = 0 +ERR_CERT_COMMON_NAME_INVALID = 0 +ERR_CERT_DATE_INVALID = 0 +ERR_CERT_AUTHORITY_INVALID = 0 +ERR_CERT_CONTAINS_ERRORS = 0 +ERR_CERT_NO_REVOCATION_MECHANISM = 0 +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = 0 +ERR_CERT_REVOKED = 0 +ERR_CERT_INVALID = 0 +ERR_CERT_END = 0 +ERR_INVALID_URL = 0 +ERR_DISALLOWED_URL_SCHEME = 0 +ERR_UNKNOWN_URL_SCHEME = 0 +ERR_TOO_MANY_REDIRECTS = 0 +ERR_UNSAFE_REDIRECT = 0 +ERR_UNSAFE_PORT = 0 +ERR_INVALID_RESPONSE = 0 +ERR_INVALID_CHUNKED_ENCODING = 0 +ERR_METHOD_NOT_SUPPORTED = 0 +ERR_UNEXPECTED_PROXY_AUTH = 0 +ERR_EMPTY_RESPONSE = 0 +ERR_RESPONSE_HEADERS_TOO_BIG = 0 +ERR_CACHE_MISS = 0 +ERR_INSECURE_RESPONSE = 0 + +# +# RequestHandler. +# + +def RequestHandler_OnResourceRedirect(browser, oldUrl, newUrl_out=[""]): + return None + +def RequestHandler_OnResourceResponse(browser, url, response, filter_out=[None]): + return None + +def RequestHandler_OnProtocolExecution(browser, url, allowOSExecution_out=[False]): + return False + +def RequestHandler_GetAuthCredentials(browser, isProxy, host, port, realm, scheme, username_out=[""], password_out=[""]): + return False + +# navType constants (OnBeforeBrowse). +NAVTYPE_LINKCLICKED = 0 +NAVTYPE_FORMSUBMITTED = 0 +NAVTYPE_BACKFORWARD = 0 +NAVTYPE_RELOAD = 0 +NAVTYPE_FORMRESUBMITTED = 0 +NAVTYPE_OTHER = 0 +NAVTYPE_LINKDROPPED = 0 + +# +# JavascriptContextHandler +# + +def JavascriptContextHandler_OnUncaughtException(browser, frame, exception, stackTrace): + return None + +# +# LifespanHandler +# + +def LifespanHandler_DoClose(browser): + return False + +def LifespanHandler_OnAfterCreated(browser): + return None + +def LifespanHandler_OnBeforeClose(browser): + return None + +def LifespanHandler_RunModal(browser): + return False + +# +# RenderHandler +# + +PET_VIEW = 0 +PET_POPUP = 0 + +KEYTYPE_KEYUP = 0 +KEYTYPE_KEYDOWN = 0 +KEYTYPE_CHAR = 0 + +MOUSEBUTTON_LEFT = 0 +MOUSEBUTTON_MIDDLE = 0 +MOUSEBUTTON_RIGHT = 0 + +def RenderHandler_GetViewRect(browser, out_rect): + return False + +def RenderHandler_GetScreenRect(browser, out_rect): + return False + +def RenderHandler_GetScreenPoint(browser, viewX, viewY, out_screenCoordinates): + return False + +def RenderHandler_OnPopupShow(browser, show): + return None + +def RenderHandler_OnPopupSize(browser, rect): + return None + +def RenderHandler_OnPaint(browser, paintElementType, out_dirtyRects, + paintBuffer): + return None + +def RenderHandler_OnCursorChange(browser, cursor): + return None diff --git a/cefpython/cef3/BUILD_COMPATIBILITY.txt b/cefpython/cef3/BUILD_COMPATIBILITY.txt new file mode 100644 index 00000000..b4fbba79 --- /dev/null +++ b/cefpython/cef3/BUILD_COMPATIBILITY.txt @@ -0,0 +1,16 @@ +Chromium/CEF branch: + 1650 +Chromium release url: + http://src.chromium.org/svn/releases/31.0.1650.69 +CEF revision: + 1639 +CEF repository url: + http://chromiumembedded.googlecode.com/svn/branches/1650/cef3@1639 + +---- + +To convert chromium revision back to version string use this url: +http://src.chromium.org/viewvc/chrome/branches/xxxx/src/chrome/VERSION?revision=xxxx + +The latest chromium version in given branch: +http://src.chromium.org/viewvc/chrome/branches/xxxx/src/chrome/VERSION diff --git a/cefpython/cef3/DebugLog.h b/cefpython/cef3/DebugLog.h new file mode 100644 index 00000000..83ffaadd --- /dev/null +++ b/cefpython/cef3/DebugLog.h @@ -0,0 +1,24 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include + +extern bool g_debug; +extern std::string g_logFile; + +// Defined as "inline" to get rid of the "already defined" errors +// when linking. +inline void DebugLog(const char* szString) +{ + if (!g_debug) + return; + // TODO: get the log_file option from CefSettings. + printf("[CEF Python] %s\n", szString); + if (g_logFile.length()) { + FILE* pFile = fopen(g_logFile.c_str(), "a"); + fprintf(pFile, "[CEF Python] App: %s\n", szString); + fclose(pFile); + } +} diff --git a/cefpython/cef3/LOG_DEBUG.h b/cefpython/cef3/LOG_DEBUG.h new file mode 100644 index 00000000..cf29ce9e --- /dev/null +++ b/cefpython/cef3/LOG_DEBUG.h @@ -0,0 +1,205 @@ +// Taken from here: http://www.drdobbs.com/cpp/logging-in-c/201804215 +// Original author: Petru Marginean +// Modified by: Czarek Tomczak + +// Usage: +// LOG_DEBUG << "Browser: someVar = " << someVar; +// Warning: +// Log is written when ~Log() destructor is called, which +// occurs when outside of scope. This could result in log +// not being written if program crashes before code goes +// outside of current scope. You could embrace LOG_DEBUG +// statements with braces {} to guarantee the log to be +// written immediately. + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include +#include +#include "DebugLog.h" + +inline std::string NowTime(); + +enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, + logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4}; + +template +class Log +{ +public: + Log(); + virtual ~Log(); + std::ostringstream& Get(TLogLevel level = logINFO); +public: + static TLogLevel& ReportingLevel(); + static std::string ToString(TLogLevel level); + static TLogLevel FromString(const std::string& level); +protected: + std::ostringstream os; +private: + Log(const Log&); + Log& operator =(const Log&); +}; + +template +Log::Log() +{ +} + +template +std::ostringstream& Log::Get(TLogLevel level) +{ + // os << "- " << NowTime(); + // os << " " << ToString(level) << ": "; + // os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); + return os; +} + +template +Log::~Log() +{ + os << std::endl; + /* + if (T::Stream() != stderr) { + fprintf(stderr, "%s", os.str().c_str()); + fflush(stderr); + } + T::Output(os.str()); + */ + DebugLog(os.str().c_str()); +} + +template +TLogLevel& Log::ReportingLevel() +{ + static TLogLevel reportingLevel = logDEBUG4; + return reportingLevel; +} + +template +std::string Log::ToString(TLogLevel level) +{ + static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", + "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; + return buffer[level]; +} + +template +TLogLevel Log::FromString(const std::string& level) +{ + if (level == "DEBUG4") + return logDEBUG4; + if (level == "DEBUG3") + return logDEBUG3; + if (level == "DEBUG2") + return logDEBUG2; + if (level == "DEBUG1") + return logDEBUG1; + if (level == "DEBUG") + return logDEBUG; + if (level == "INFO") + return logINFO; + if (level == "WARNING") + return logWARNING; + if (level == "ERROR") + return logERROR; + Log().Get(logWARNING) << "Unknown logging level '" << level + << "'. Using INFO level as default."; + return logINFO; +} + +class Output2FILE +{ +public: + static FILE*& Stream(); + static void Output(const std::string& msg); +}; + +inline FILE*& Output2FILE::Stream() +{ + static FILE* pStream = stderr; + return pStream; +} + +inline void Output2FILE::Output(const std::string& msg) +{ + /* + FILE* pStream = Stream(); + if (!pStream) + return; + fprintf(pStream, "%s", msg.c_str()); + fflush(pStream); + */ +} + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined (BUILDING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllexport) +# elif defined (USING_FILELOG_DLL) +# define FILELOG_DECLSPEC __declspec (dllimport) +# else +# define FILELOG_DECLSPEC +# endif // BUILDING_DBSIMPLE_DLL +#else +# define FILELOG_DECLSPEC +#endif // _WIN32 + +class FILELOG_DECLSPEC FILELog : public Log {}; +//typedef Log FILELog; + +#ifndef FILELOG_MAX_LEVEL +#define FILELOG_MAX_LEVEL logDEBUG4 +#endif + +#define LOG(level) \ + if (level > FILELOG_MAX_LEVEL) ;\ + else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \ + else FILELog().Get(level) \ + +#define LOG_ERROR LOG(logERROR) +#define LOG_WARNING LOG(logWARNING) +#define LOG_INFO LOG(logINFO) +#define LOG_DEBUG LOG(logDEBUG) + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + +#include + +inline std::string NowTime() +{ + const int MAX_LEN = 200; + char buffer[MAX_LEN]; + if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0, + "HH':'mm':'ss", buffer, MAX_LEN) == 0) + return "Error in NowTime()"; + + char result[100] = {0}; + static DWORD first = GetTickCount(); + #pragma warning(suppress: 4996) + sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000); + return result; +} + +#else + +#include + +inline std::string NowTime() +{ + char buffer[11]; + time_t t; + time(&t); + tm r = {0}; + strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r)); + struct timeval tv; + gettimeofday(&tv, 0); + char result[100] = {0}; + sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); + return result; +} + +#endif //WIN32 + +#endif //__LOG_H__ diff --git a/cefpython/cef3/cefpython_public_api.h b/cefpython/cef3/cefpython_public_api.h new file mode 100644 index 00000000..637dbdad --- /dev/null +++ b/cefpython/cef3/cefpython_public_api.h @@ -0,0 +1,40 @@ +// d:\cefpython\src\setup/cefpython.h(22) : warning C4190: 'RequestHandler_GetCookieManager' +// has C-linkage specified, but returns UDT 'CefRefPtr' which is incompatible with C + +#ifndef CEFPYTHON_PUBLIC_API_H +#define CEFPYTHON_PUBLIC_API_H + +#if defined(OS_WIN) +#pragma warning(disable:4190) +#endif + +// To be able to use 'public' declarations you need to include Python.h and cefpython.h. +// This include must be before including CEF, otherwise you get errors like: +// | /usr/include/python2.7/pyconfig.h:1161:0: warning: "_POSIX_C_SOURCE" redefined +// This file needs to be included first before CEF. +#include "Python.h" + +// All the imports that are required when including "cefpython.h". +#include "include/cef_client.h" +#include "include/cef_urlrequest.h" +#include "include/cef_command_line.h" +#include "util.h" + +// Python 3.2 fix - DL_IMPORT is not defined in Python.h +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +#if defined(OS_WIN) +#include "windows/setup/cefpython.h" +#elif defined(OS_LINUX) +#include "linux/setup/cefpython.h" +#elif defined(OS_MACOSX) +#include "mac/setup/cefpython.h" +#endif + +// CEFPYTHON_PUBLIC_API_H +#endif diff --git a/cefpython/cef3/client_handler/.gitignore b/cefpython/cef3/client_handler/.gitignore new file mode 100644 index 00000000..151a620f --- /dev/null +++ b/cefpython/cef3/client_handler/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a \ No newline at end of file diff --git a/cefpython/cef3/client_handler/Makefile b/cefpython/cef3/client_handler/Makefile new file mode 100644 index 00000000..332b8508 --- /dev/null +++ b/cefpython/cef3/client_handler/Makefile @@ -0,0 +1,50 @@ +# -g - extra debug information +# -O1 - more precise backtraces +# -fPIC - required when using -shared option, required for use with Cython +# -Wall - show important warnings +# -Werror - treat warnings as errors + +# Cython compiler options: +# -fPIC -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions \ +# -Wl,-z,relro + +UNAME_S = $(shell uname -s) + +CC = g++ +CCFLAGS = -g -fPIC -Wall -Werror $(CEF_CCFLAGS) + +SRC = client_handler.cpp cookie_visitor.cpp resource_handler.cpp \ + web_request_client.cpp string_visitor.cpp request_context_handler.cpp \ + task.cpp + +OBJ = $(SRC:.cpp=.o) + +ifeq ($(UNAME_S), Darwin) + OBJ += util_mac.o +endif + +OUT = libclient_handler.a + +INC = -I./../ -I/usr/include/python2.7 -I/usr/include/gtk-2.0 \ + -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \ + -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \ + -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \ + -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ + -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ + -I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \ + -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include + +.cpp.o: + @echo [Makefile] Building $@ from $<... + $(CC) $(CCFLAGS) $(INC) -c $< -o $@ + +$(OUT): $(OBJ) + @echo [Makefile] Creating library $(OUT) from $(OBJ)... + ar rcs $(OUT) $(OBJ) + +util_mac.o: util_mac.mm + @echo [Makefile] Building $@ from $<... + $(CC) $(CCFLAGS) $(INC) -c $< -o $@ + +clean: + rm *.o *.a diff --git a/cefpython/cef3/client_handler/client_handler.cpp b/cefpython/cef3/client_handler/client_handler.cpp new file mode 100644 index 00000000..ad366b12 --- /dev/null +++ b/cefpython/cef3/client_handler/client_handler.cpp @@ -0,0 +1,1017 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// ClientHandler code is running in the Browser process only. + +#include "client_handler.h" +#include "cefpython_public_api.h" +#include "DebugLog.h" +#include "LOG_DEBUG.h" + +#if defined(OS_WIN) +#include +#pragma comment(lib, "Shell32.lib") +#include "dpi_aware.h" +#elif defined(OS_LINUX) +#include +#include +#endif + +// ---------------------------------------------------------------------------- +// Linux equivalent of ShellExecute +// ---------------------------------------------------------------------------- + +#if defined(OS_LINUX) +void OpenInExternalBrowser(const std::string& url) +{ + if (url.empty()) { + DebugLog("Browser: OpenInExternalBrowser() FAILED: url is empty"); + return; + } + std::string msg = "Browser: OpenInExternalBrowser(): url="; + msg.append(url.c_str()); + DebugLog(msg.c_str()); + + // xdg-open is a desktop-independent tool for running + // default applications. Installed by default on Ubuntu. + // xdg-open process is running in the backround until + // cefpython app closes. + std::string prog = "xdg-open"; + + // Using system() opens up for bugs and exploits, not + // recommended. + + // Fork yourself and run in parallel, do not block the + // current proces. + char *args[3]; + args[0] = (char*) prog.c_str(); + args[1] = (char*) url.c_str(); + args[2] = 0; + pid_t pid = fork(); + if (!pid) { + execvp(prog.c_str(), args); + } +} +#endif + +// ---------------------------------------------------------------------------- +// CefClient +// ---------------------------------------------------------------------------- + +bool ClientHandler::OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + if (source_process != PID_RENDERER) { + return false; + } + std::string messageName = message->GetName().ToString(); + std::string logMessage = "Browser: OnProcessMessageReceived(): "; + logMessage.append(messageName.c_str()); + DebugLog(logMessage.c_str()); + if (messageName == "OnContextCreated") { + CefRefPtr arguments = message->GetArgumentList(); + if (arguments->GetSize() == 1 && arguments->GetType(0) == VTYPE_INT) { + int64 frameId = arguments->GetInt(0); + CefRefPtr frame = browser->GetFrame(frameId); + V8ContextHandler_OnContextCreated(browser, frame); + return true; + } else { + DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \ + ", messageName = OnContextCreated"); + return false; + } + } else if (messageName == "OnContextReleased") { + CefRefPtr arguments = message->GetArgumentList(); + if (arguments->GetSize() == 2 \ + && arguments->GetType(0) == VTYPE_INT \ + && arguments->GetType(1) == VTYPE_INT) { + int browserId = arguments->GetInt(0); + int64 frameId = arguments->GetInt(1); + V8ContextHandler_OnContextReleased(browserId, frameId); + return true; + } else { + DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \ + ", messageName = OnContextReleased"); + return false; + } + } else if (messageName == "V8FunctionHandler::Execute") { + CefRefPtr arguments = message->GetArgumentList(); + if (arguments->GetSize() == 3 + && arguments->GetType(0) == VTYPE_INT // frameId + && arguments->GetType(1) == VTYPE_STRING // functionName + && arguments->GetType(2) == VTYPE_LIST) { // functionArguments + int64 frameId = arguments->GetInt(0); + CefString functionName = arguments->GetString(1); + CefRefPtr functionArguments = arguments->GetList(2); + CefRefPtr frame = browser->GetFrame(frameId); + V8FunctionHandler_Execute(browser, frame, functionName, functionArguments); + return true; + } else { + DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \ + ", messageName = V8FunctionHandler::Execute"); + return false; + } + } else if (messageName == "ExecutePythonCallback") { + CefRefPtr arguments = message->GetArgumentList(); + if (arguments->GetSize() == 2 + && arguments->GetType(0) == VTYPE_INT // callbackId + && arguments->GetType(1) == VTYPE_LIST) { // functionArguments + int callbackId = arguments->GetInt(0); + CefRefPtr functionArguments = arguments->GetList(1); + ExecutePythonCallback(browser, callbackId, functionArguments); + return true; + } else { + DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \ + ", messageName = ExecutePythonCallback"); + return false; + } + } else if (messageName == "RemovePythonCallbacksForFrame") { + CefRefPtr arguments = message->GetArgumentList(); + if (arguments->GetSize() == 1 && arguments->GetType(0) == VTYPE_INT) { + int frameId = arguments->GetInt(0); + RemovePythonCallbacksForFrame(frameId); + return true; + } else { + DebugLog("Browser: OnProcessMessageReceived(): invalid arguments" \ + ", messageName = ExecutePythonCallback"); + return false; + } + } + return false; +} + +// ---------------------------------------------------------------------------- +// CefLifeSpanHandler +// ---------------------------------------------------------------------------- + +/// +// Called on the IO thread before a new popup window is created. The |browser| +// and |frame| parameters represent the source of the popup request. The +// |target_url| and |target_frame_name| values may be empty if none were +// specified with the request. The |popupFeatures| structure contains +// information about the requested popup window. To allow creation of the +// popup window optionally modify |windowInfo|, |client|, |settings| and +// |no_javascript_access| and return false. To cancel creation of the popup +// window return true. The |client| and |settings| values will default to the +// source browser's values. The |no_javascript_access| value indicates whether +// the new browser window should be scriptable and in the same process as the +// source browser. +/*--cef(optional_param=target_url,optional_param=target_frame_name)--*/ +bool ClientHandler::OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) { + REQUIRE_IO_THREAD(); + // Note: passing popupFeatures is not yet supported. + return LifespanHandler_OnBeforePopup(browser, frame, target_url, + target_frame_name, 0, windowInfo, client, settings, + no_javascript_access); +} + +/// +// Called after a new browser is created. +/// +/*--cef()--*/ +void ClientHandler::OnAfterCreated(CefRefPtr browser) { + REQUIRE_UI_THREAD(); +#if defined(OS_WIN) + // High DPI support. + CefString auto_zooming = ApplicationSettings_GetString("auto_zooming"); + if (!auto_zooming.empty()) { + LOG_DEBUG << "Browser: OnAfterCreated(): auto_zooming = " + << auto_zooming.ToString(); + SetBrowserDpiSettings(browser, auto_zooming); + } +#endif + LifespanHandler_OnAfterCreated(browser); +} + +/// +// Called when a modal window is about to display and the modal loop should +// begin running. Return false to use the default modal loop implementation or +// true to use a custom implementation. +/// +/*--cef()--*/ +bool ClientHandler::RunModal(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return LifespanHandler_RunModal(browser); +} + +/// +// Called when a browser has recieved a request to close. This may result +// directly from a call to CefBrowserHost::CloseBrowser() or indirectly if the +// browser is a top-level OS window created by CEF and the user attempts to +// close the window. This method will be called after the JavaScript +// 'onunload' event has been fired. It will not be called for browsers after +// the associated OS window has been destroyed (for those browsers it is no +// longer possible to cancel the close). +// +// If CEF created an OS window for the browser returning false will send an OS +// close notification to the browser window's top-level owner (e.g. WM_CLOSE +// on Windows, performClose: on OS-X and "delete_event" on Linux). If no OS +// window exists (window rendering disabled) returning false will cause the +// browser object to be destroyed immediately. Return true if the browser is +// parented to another window and that other window needs to receive close +// notification via some non-standard technique. +// +// If an application provides its own top-level window it should handle OS +// close notifications by calling CefBrowserHost::CloseBrowser(false) instead +// of immediately closing (see the example below). This gives CEF an +// opportunity to process the 'onbeforeunload' event and optionally cancel the +// close before DoClose() is called. +// +// The CefLifeSpanHandler::OnBeforeClose() method will be called immediately +// before the browser object is destroyed. The application should only exit +// after OnBeforeClose() has been called for all existing browsers. +// +// If the browser represents a modal window and a custom modal loop +// implementation was provided in CefLifeSpanHandler::RunModal() this callback +// should be used to restore the opener window to a usable state. +// +// By way of example consider what should happen during window close when the +// browser is parented to an application-provided top-level OS window. +// 1. User clicks the window close button which sends an OS close +// notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and +// "delete_event" on Linux). +// 2. Application's top-level window receives the close notification and: +// A. Calls CefBrowserHost::CloseBrowser(false). +// B. Cancels the window close. +// 3. JavaScript 'onbeforeunload' handler executes and shows the close +// confirmation dialog (which can be overridden via +// CefJSDialogHandler::OnBeforeUnloadDialog()). +// 4. User approves the close. +// 5. JavaScript 'onunload' handler executes. +// 6. Application's DoClose() handler is called. Application will: +// A. Call CefBrowserHost::ParentWindowWillClose() to notify CEF that the +// parent window will be closing. +// B. Set a flag to indicate that the next close attempt will be allowed. +// C. Return false. +// 7. CEF sends an OS close notification. +// 8. Application's top-level window receives the OS close notification and +// allows the window to close based on the flag from #6B. +// 9. Browser OS window is destroyed. +// 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and +// the browser object is destroyed. +// 11. Application exits by calling CefQuitMessageLoop() if no other browsers +// exist. +/// +/*--cef()--*/ +bool ClientHandler::DoClose(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return LifespanHandler_DoClose(browser); +} + +/// +// Called just before a browser is destroyed. Release all references to the +// browser object and do not attempt to execute any methods on the browser +// object after this callback returns. If this is a modal window and a custom +// modal loop implementation was provided in RunModal() this callback should +// be used to exit the custom modal loop. See DoClose() documentation for +// additional usage information. +/// +/*--cef()--*/ +void ClientHandler::OnBeforeClose(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + LifespanHandler_OnBeforeClose(browser); +} + +// -------------------------------------------------------------------------- +// CefDisplayHandler +// -------------------------------------------------------------------------- + +/// +// Implement this interface to handle events related to browser display state. +// The methods of this class will be called on the UI thread. +/// + +/// +// Called when a frame's address has changed. +/// +/*--cef()--*/ +void ClientHandler::OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnAddressChange(browser, frame, url); +} + +/// +// Called when the page title changes. +/// +/*--cef(optional_param=title)--*/ +void ClientHandler::OnTitleChange(CefRefPtr browser, + const CefString& title) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnTitleChange(browser, title); +} + +/// +// Called when the browser is about to display a tooltip. |text| contains the +// text that will be displayed in the tooltip. To handle the display of the +// tooltip yourself return true. Otherwise, you can optionally modify |text| +// and then return false to allow the browser to display the tooltip. +// When window rendering is disabled the application is responsible for +// drawing tooltips and the return value is ignored. +/// +/*--cef(optional_param=text)--*/ +bool ClientHandler::OnTooltip(CefRefPtr browser, + CefString& text) { + REQUIRE_UI_THREAD(); + return DisplayHandler_OnTooltip(browser, text); + // return false; +} + +/// +// Called when the browser receives a status message. |text| contains the text +// that will be displayed in the status message and |type| indicates the +// status message type. +/// +/*--cef(optional_param=value)--*/ +void ClientHandler::OnStatusMessage(CefRefPtr browser, + const CefString& value) { + REQUIRE_UI_THREAD(); + DisplayHandler_OnStatusMessage(browser, value); +} + +/// +// Called to display a console message. Return true to stop the message from +// being output to the console. +/// +/*--cef(optional_param=message,optional_param=source)--*/ +bool ClientHandler::OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) { + REQUIRE_UI_THREAD(); + return DisplayHandler_OnConsoleMessage(browser, message, source, line); + // return false; +} + +// ---------------------------------------------------------------------------- +// CefKeyboardHandler +// ---------------------------------------------------------------------------- + +/// +// Implement this interface to handle events related to keyboard input. The +// methods of this class will be called on the UI thread. +/// + +// Called before a keyboard event is sent to the renderer. |event| contains +// information about the keyboard event. |os_event| is the operating system +// event message, if any. Return true if the event was handled or false +// otherwise. If the event will be handled in OnKeyEvent() as a keyboard +// shortcut set |is_keyboard_shortcut| to true and return false. +/*--cef()--*/ +bool ClientHandler::OnPreKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event, + bool* is_keyboard_shortcut) { + REQUIRE_UI_THREAD(); + return KeyboardHandler_OnPreKeyEvent(browser, event, os_event, + is_keyboard_shortcut); + // Default: return false; +} + +/// +// Called after the renderer and JavaScript in the page has had a chance to +// handle the event. |event| contains information about the keyboard event. +// |os_event| is the operating system event message, if any. Return true if +// the keyboard event was handled or false otherwise. +/// +/*--cef()--*/ +bool ClientHandler::OnKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event) { + REQUIRE_UI_THREAD(); + return KeyboardHandler_OnKeyEvent(browser, event, os_event); + // Default: return false; +} + +// -------------------------------------------------------------------------- +// CefRequestHandler +// -------------------------------------------------------------------------- + +/// +// Implement this interface to handle events related to browser requests. The +// methods of this class will be called on the thread indicated. +/// + +/// +// Called on the UI thread before browser navigation. Return true to cancel +// the navigation or false to allow the navigation to proceed. The |request| +// object cannot be modified in this callback. +// CefLoadHandler::OnLoadingStateChange will be called twice in all cases. +// If the navigation is allowed CefLoadHandler::OnLoadStart and +// CefLoadHandler::OnLoadEnd will be called. If the navigation is canceled +// CefLoadHandler::OnLoadError will be called with an |errorCode| value of +// ERR_ABORTED. +/// +/*--cef()--*/ +bool ClientHandler::OnBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + bool is_redirect) { + REQUIRE_UI_THREAD(); + return RequestHandler_OnBeforeBrowse(browser, frame, request, is_redirect); +} + +/// +// Called on the IO thread before a resource request is loaded. The |request| +// object may be modified. To cancel the request return true otherwise return +// false. +/// +/*--cef()--*/ +bool ClientHandler::OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) { + REQUIRE_IO_THREAD(); + return RequestHandler_OnBeforeResourceLoad(browser, frame, request); + // Default: return false; +} + +/// +// Called on the IO thread before a resource is loaded. To allow the resource +// to load normally return NULL. To specify a handler for the resource return +// a CefResourceHandler object. The |request| object should not be modified in +// this callback. +/// +/*--cef()--*/ +CefRefPtr ClientHandler::GetResourceHandler( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) { + REQUIRE_IO_THREAD(); + return RequestHandler_GetResourceHandler(browser, frame, request); +} + +/// +// Called on the IO thread when a resource load is redirected. The |old_url| +// parameter will contain the old URL. The |new_url| parameter will contain +// the new URL and can be changed if desired. +/// +/*--cef()--*/ +void ClientHandler::OnResourceRedirect(CefRefPtr browser, + CefRefPtr frame, + const CefString& old_url, + CefString& new_url) { + REQUIRE_IO_THREAD(); + RequestHandler_OnResourceRedirect(browser, frame, old_url, new_url); +} + +/// +// Called on the IO thread when the browser needs credentials from the user. +// |isProxy| indicates whether the host is a proxy server. |host| contains the +// hostname and |port| contains the port number. Return true to continue the +// request and call CefAuthCallback::Continue() when the authentication +// information is available. Return false to cancel the request. +/// +/*--cef(optional_param=realm)--*/ +bool ClientHandler::GetAuthCredentials(CefRefPtr browser, + CefRefPtr frame, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) { + REQUIRE_IO_THREAD(); + return RequestHandler_GetAuthCredentials(browser, frame, isProxy, host, + port, realm, scheme, callback); + // Default: return false; +} + +/// +// Called on the IO thread when JavaScript requests a specific storage quota +// size via the webkitStorageInfo.requestQuota function. |origin_url| is the +// origin of the page making the request. |new_size| is the requested quota +// size in bytes. Return true and call CefQuotaCallback::Continue() either in +// this method or at a later time to grant or deny the request. Return false +// to cancel the request. +/// +/*--cef(optional_param=realm)--*/ +bool ClientHandler::OnQuotaRequest(CefRefPtr browser, + const CefString& origin_url, + int64 new_size, + CefRefPtr callback) { + REQUIRE_IO_THREAD(); + return RequestHandler_OnQuotaRequest(browser, origin_url, new_size, + callback); + // Default: return false; +} + +/// +// Called on the UI thread to handle requests for URLs with an unknown +// protocol component. Set |allow_os_execution| to true to attempt execution +// via the registered OS protocol handler, if any. +// SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED +// ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. +/// +/*--cef()--*/ +void ClientHandler::OnProtocolExecution(CefRefPtr browser, + const CefString& url, + bool& allow_os_execution) { + REQUIRE_UI_THREAD(); + RequestHandler_OnProtocolExecution(browser, url, allow_os_execution); +} + +/// +// Called on the browser process IO thread before a plugin is loaded. Return +// true to block loading of the plugin. +/// +/*--cef(optional_param=url,optional_param=policy_url)--*/ +bool ClientHandler::OnBeforePluginLoad(CefRefPtr browser, + const CefString& url, + const CefString& policy_url, + CefRefPtr info) { + REQUIRE_IO_THREAD(); + return RequestHandler_OnBeforePluginLoad(browser, url, policy_url, info); + // Default: return false; +} + +/// +// Called on the UI thread to handle requests for URLs with an invalid +// SSL certificate. Return true and call CefAllowCertificateErrorCallback:: +// Continue() either in this method or at a later time to continue or cancel +// the request. Return false to cancel the request immediately. If |callback| +// is empty the error cannot be recovered from and the request will be +// canceled automatically. If CefSettings.ignore_certificate_errors is set +// all invalid certificates will be accepted without calling this method. +/// +/*--cef()--*/ +bool ClientHandler::OnCertificateError( + cef_errorcode_t cert_error, + const CefString& request_url, + CefRefPtr callback) { + REQUIRE_UI_THREAD(); + return RequestHandler_OnCertificateError( + cert_error, request_url, callback); + // Default: return false; +} + +/// +// Called when the render process terminates unexpectedly. |status| indicates +// how the process terminated. +/// +/*--cef()--*/ +void ClientHandler::OnRenderProcessTerminated(CefRefPtr browser, + cef_termination_status_t status) { + REQUIRE_UI_THREAD(); + DebugLog("Browser: OnRenderProcessTerminated()"); + RequestHandler_OnRendererProcessTerminated(browser, status); +} + +/// +// Called when a plugin has crashed. |plugin_path| is the path of the plugin +// that crashed. +/// +/*--cef()--*/ +void ClientHandler::OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) { + REQUIRE_UI_THREAD(); + RequestHandler_OnPluginCrashed(browser, plugin_path); +} + +// -------------------------------------------------------------------------- +// CefLoadHandler +// -------------------------------------------------------------------------- + +/// +// Implement this interface to handle events related to browser load status. +// The methods of this class will be called on the UI thread. +/// + +/// +// Called when the loading state has changed. +/// +/*--cef()--*/ +void ClientHandler::OnLoadingStateChange(CefRefPtr browser, + bool isLoading, + bool canGoBack, + bool canGoForward) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadingStateChange(browser, isLoading, canGoBack, + canGoForward); +} + +/// +// Called when the browser begins loading a frame. The |frame| value will +// never be empty -- call the IsMain() method to check if this frame is the +// main frame. Multiple frames may be loading at the same time. Sub-frames may +// start or continue loading after the main frame load has ended. This method +// may not be called for a particular frame if the load request for that frame +// fails. +/// +/*--cef()--*/ +void ClientHandler::OnLoadStart(CefRefPtr browser, + CefRefPtr frame) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadStart(browser, frame); +} + +/// +// Called when the browser is done loading a frame. The |frame| value will +// never be empty -- call the IsMain() method to check if this frame is the +// main frame. Multiple frames may be loading at the same time. Sub-frames may +// start or continue loading after the main frame load has ended. This method +// will always be called for all frames irrespective of whether the request +// completes successfully. +/// +/*--cef()--*/ +void ClientHandler::OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadEnd(browser, frame, httpStatusCode); +} + +/// +// Called when the browser fails to load a resource. |errorCode| is the error +// code number, |errorText| is the error text and and |failedUrl| is the URL +// that failed to load. See net\base\net_error_list.h for complete +// descriptions of the error codes. +/// +/*--cef(optional_param=errorText)--*/ +void ClientHandler::OnLoadError(CefRefPtr browser, + CefRefPtr frame, + cef_errorcode_t errorCode, + const CefString& errorText, + const CefString& failedUrl) { + REQUIRE_UI_THREAD(); + LoadHandler_OnLoadError(browser, frame, errorCode, errorText, failedUrl); +} + +// ---------------------------------------------------------------------------- +// CefRenderHandler +// ---------------------------------------------------------------------------- + +/// +// Implement this interface to handle events when window rendering is disabled. +// The methods of this class will be called on the UI thread. +/// + +/// +// Called to retrieve the root window rectangle in screen coordinates. Return +// true if the rectangle was provided. +/// +/*--cef()--*/ +bool ClientHandler::GetRootScreenRect(CefRefPtr browser, + CefRect& rect) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetRootScreenRect(browser, rect); +} + +/// +// Called to retrieve the view rectangle which is relative to screen +// coordinates. Return true if the rectangle was provided. +/// +/*--cef()--*/ +bool ClientHandler::GetViewRect(CefRefPtr browser, CefRect& rect) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetViewRect(browser, rect); +} + +/// +// Called to retrieve the translation from view coordinates to actual screen +// coordinates. Return true if the screen coordinates were provided. +/// +/*--cef()--*/ +bool ClientHandler::GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetScreenPoint(browser, viewX, viewY, screenX, + screenY); +} + +/// +// Called to allow the client to fill in the CefScreenInfo object with +// appropriate values. Return true if the |screen_info| structure has been +// modified. +// +// If the screen info rectangle is left empty the rectangle from GetViewRect +// will be used. If the rectangle is still empty or invalid popups may not be +// drawn correctly. +/// +/*--cef()--*/ +bool ClientHandler::GetScreenInfo(CefRefPtr browser, + CefScreenInfo& screen_info) { + REQUIRE_UI_THREAD(); + return RenderHandler_GetScreenInfo(browser, screen_info); +} + +/// +// Called when the browser wants to show or hide the popup widget. The popup +// should be shown if |show| is true and hidden if |show| is false. +/// +/*--cef()--*/ +void ClientHandler::OnPopupShow(CefRefPtr browser, + bool show) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPopupShow(browser, show); +} + +/// +// Called when the browser wants to move or resize the popup widget. |rect| +// contains the new location and size. +/// +/*--cef()--*/ +void ClientHandler::OnPopupSize(CefRefPtr browser, + const CefRect& rect) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPopupSize(browser, rect); +} + +/// +// Called when an element should be painted. |type| indicates whether the +// element is the view or the popup widget. |buffer| contains the pixel data +// for the whole image. |dirtyRects| contains the set of rectangles that need +// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes +// in size and represents a BGRA image with an upper-left origin. +/// +/*--cef()--*/ +void ClientHandler::OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) { + REQUIRE_UI_THREAD(); + RenderHandler_OnPaint(browser, type, const_cast(dirtyRects), \ + buffer, width, height); +}; + +/// +// Called when the browser window's cursor has changed. +/// +/*--cef()--*/ +void ClientHandler::OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) { + REQUIRE_UI_THREAD(); + RenderHandler_OnCursorChange(browser, cursor); +} + +/// +// Called when the scroll offset has changed. +/// +/*--cef()--*/ +void ClientHandler::OnScrollOffsetChanged(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + RenderHandler_OnScrollOffsetChanged(browser); +} + + +// ---------------------------------------------------------------------------- +// CefJSDialogHandler +// ---------------------------------------------------------------------------- +/// +// Called to run a JavaScript dialog. The |default_prompt_text| value will be +// specified for prompt dialogs only. Set |suppress_message| to true and +// return false to suppress the message (suppressing messages is preferable +// to immediately executing the callback as this is used to detect presumably +// malicious behavior like spamming alert messages in onbeforeunload). Set +// |suppress_message| to false and return false to use the default +// implementation (the default implementation will show one modal dialog at a +// time and suppress any additional dialog requests until the displayed dialog +// is dismissed). Return true if the application will use a custom dialog or +// if the callback has been executed immediately. Custom dialogs may be either +// modal or modeless. If a custom dialog is used the application must execute +// |callback| once the custom dialog is dismissed. +/// +/*--cef(optional_param=accept_lang,optional_param=message_text, + optional_param=default_prompt_text)--*/ +bool ClientHandler::OnJSDialog(CefRefPtr browser, + const CefString& origin_url, + const CefString& accept_lang, + JSDialogType dialog_type, + const CefString& message_text, + const CefString& default_prompt_text, + CefRefPtr callback, + bool& suppress_message) { + REQUIRE_UI_THREAD(); + return JavascriptDialogHandler_OnJavascriptDialog(browser, origin_url, + accept_lang, dialog_type, message_text, default_prompt_text, + callback, suppress_message); +} + +/// +// Called to run a dialog asking the user if they want to leave a page. Return +// false to use the default dialog implementation. Return true if the +// application will use a custom dialog or if the callback has been executed +// immediately. Custom dialogs may be either modal or modeless. If a custom +// dialog is used the application must execute |callback| once the custom +// dialog is dismissed. +/// +/*--cef(optional_param=message_text)--*/ +bool ClientHandler::OnBeforeUnloadDialog(CefRefPtr browser, + const CefString& message_text, + bool is_reload, + CefRefPtr callback) { + REQUIRE_UI_THREAD(); + return JavascriptDialogHandler_OnBeforeUnloadJavascriptDialog(browser, + message_text, is_reload, callback); +} + +/// +// Called to cancel any pending dialogs and reset any saved dialog state. Will +// be called due to events like page navigation irregardless of whether any +// dialogs are currently pending. +/// +/*--cef()--*/ +void ClientHandler::OnResetDialogState(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return JavascriptDialogHandler_OnResetJavascriptDialogState(browser); +} + +/// +// Called when the default implementation dialog is closed. +/// +/*--cef()--*/ +void ClientHandler::OnDialogClosed(CefRefPtr browser) { + REQUIRE_UI_THREAD(); + return JavascriptDialogHandler_OnJavascriptDialogClosed(browser); +} + +// ---------------------------------------------------------------------------- +// CefDownloadHandler +// ---------------------------------------------------------------------------- + +/// +// Class used to handle file downloads. The methods of this class will called +// on the browser process UI thread. +/// + +/// +// Called before a download begins. |suggested_name| is the suggested name for +// the download file. By default the download will be canceled. Execute +// |callback| either asynchronously or in this method to continue the download +// if desired. Do not keep a reference to |download_item| outside of this +// method. +/// +/*--cef()--*/ +void ClientHandler::OnBeforeDownload(CefRefPtr browser, + CefRefPtr download_item, + const CefString& suggested_name, + CefRefPtr callback) { + REQUIRE_UI_THREAD(); + bool downloads_enabled = ApplicationSettings_GetBool("downloads_enabled"); + if (downloads_enabled) { + std::string msg = "Browser: About to download file: "; + msg.append(suggested_name.ToString().c_str()); + DebugLog(msg.c_str()); + callback->Continue(suggested_name, true); + } else { + DebugLog("Browser: Tried to download file, but downloads are disabled"); + } +} + +/// +// Called when a download's status or progress information has been updated. +// This may be called multiple times before and after OnBeforeDownload(). +// Execute |callback| either asynchronously or in this method to cancel the +// download if desired. Do not keep a reference to |download_item| outside of +// this method. +/// +/*--cef()--*/ +void ClientHandler::OnDownloadUpdated( + CefRefPtr browser, + CefRefPtr download_item, + CefRefPtr callback) { + REQUIRE_UI_THREAD(); + if (download_item->IsComplete()) { + std::string msg = "Browser: Download completed, saved to: "; + msg.append(download_item->GetFullPath().ToString().c_str()); + DebugLog(msg.c_str()); + } else if (download_item->IsCanceled()) { + DebugLog("Browser: Download was cancelled"); + } +} + +// ---------------------------------------------------------------------------- +// CefContextMenuHandler +// ---------------------------------------------------------------------------- + +#define _MENU_ID_DEVTOOLS MENU_ID_USER_FIRST + 1 +#define _MENU_ID_RELOAD_PAGE MENU_ID_USER_FIRST + 2 +#define _MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER MENU_ID_USER_FIRST + 3 +#define _MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER MENU_ID_USER_FIRST + 4 + +/// +// Called before a context menu is displayed. |params| provides information +// about the context menu state. |model| initially contains the default +// context menu. The |model| can be cleared to show no context menu or +// modified to show a custom menu. Do not keep references to |params| or +// |model| outside of this callback. +/// +/*--cef()--*/ +void ClientHandler::OnBeforeContextMenu(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + CefRefPtr model) { + bool enabled = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "enabled"); + bool navigation = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "navigation"); + bool print = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "print"); + bool view_source = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "view_source"); + bool external_browser = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "external_browser"); + bool devtools = ApplicationSettings_GetBoolFromDict(\ + "context_menu", "devtools"); + + if (!enabled) { + model->Clear(); + return; + } + if (!navigation) { + model->Remove(MENU_ID_BACK); + model->Remove(MENU_ID_FORWARD); + // Remove separator + model->RemoveAt(0); + } + if (!print) { + model->Remove(MENU_ID_PRINT); + } + if (!view_source) { + model->Remove(MENU_ID_VIEW_SOURCE); + } + if (!params->IsEditable() && params->GetSelectionText().empty() + && (params->GetPageUrl().length() + || params->GetFrameUrl().length())) { + if (external_browser) { + model->AddItem(_MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER, + "Open in external browser"); + if (params->GetFrameUrl().length() + && params->GetPageUrl() != params->GetFrameUrl()) { + model->AddItem(_MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER, + "Open frame in external browser"); + } + } + if (navigation) { + model->InsertItemAt(2, _MENU_ID_RELOAD_PAGE, "Reload"); + } + if (devtools) { + model->AddSeparator(); + model->AddItem(_MENU_ID_DEVTOOLS, "Developer Tools"); + } + } +} + +/// +// Called to execute a command selected from the context menu. Return true if +// the command was handled or false for the default implementation. See +// cef_menu_id_t for the command ids that have default implementations. All +// user-defined command ids should be between MENU_ID_USER_FIRST and +// MENU_ID_USER_LAST. |params| will have the same values as what was passed to +// OnBeforeContextMenu(). Do not keep a reference to |params| outside of this +// callback. +/// +/*--cef()--*/ +bool ClientHandler::OnContextMenuCommand(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + int command_id, + EventFlags event_flags) { + if (command_id == _MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER) { +#if defined(OS_WIN) + ShellExecuteA(0, "open", params->GetPageUrl().ToString().c_str(), + 0, 0, SW_SHOWNORMAL); +#elif defined(OS_LINUX) + OpenInExternalBrowser(params->GetPageUrl().ToString()); +#endif + return true; + } else if (command_id == _MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER) { +#if defined(OS_WIN) + ShellExecuteA(0, "open", params->GetFrameUrl().ToString().c_str(), + 0, 0, SW_SHOWNORMAL); +#elif defined(OS_LINUX) + OpenInExternalBrowser(params->GetFrameUrl().ToString()); +#endif + return true; + } else if (command_id == _MENU_ID_RELOAD_PAGE) { + browser->ReloadIgnoreCache(); + return true; + } else if (command_id == _MENU_ID_DEVTOOLS) { + PyBrowser_ShowDevTools(browser); + return true; + } + return false; +} + +/// +// Called when the context menu is dismissed irregardless of whether the menu +// was empty or a command was selected. +/// +/*--cef()--*/ +void ClientHandler::OnContextMenuDismissed(CefRefPtr browser, + CefRefPtr frame) { +} + diff --git a/cefpython/cef3/client_handler/client_handler.h b/cefpython/cef3/client_handler/client_handler.h new file mode 100644 index 00000000..7627f8ff --- /dev/null +++ b/cefpython/cef3/client_handler/client_handler.h @@ -0,0 +1,800 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// ClientHandler code is running in the Browser process only. + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class ClientHandler : + public CefClient, + public CefLifeSpanHandler, + public CefDisplayHandler, + public CefKeyboardHandler, + public CefRequestHandler, + public CefLoadHandler, + public CefRenderHandler, + public CefJSDialogHandler, + public CefDownloadHandler, + public CefContextMenuHandler +{ +public: + ClientHandler(){} + virtual ~ClientHandler(){} + + /// + // Return the handler for context menus. If no handler is provided the default + // implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetContextMenuHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for dialogs. If no handler is provided the default + // implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetDialogHandler() OVERRIDE { + return NULL; + } + + /// + // Return the handler for browser display state events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDisplayHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for download events. If no handler is returned downloads + // will not be allowed. + /// + /*--cef()--*/ + virtual CefRefPtr GetDownloadHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for drag events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDragHandler() OVERRIDE { + return NULL; + } + + /// + // Return the handler for focus events. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusHandler() OVERRIDE { + return NULL; + } + + /// + // Return the handler for geolocation permissions requests. If no handler is + // provided geolocation access will be denied by default. + /// + /*--cef()--*/ + virtual CefRefPtr GetGeolocationHandler() OVERRIDE { + return NULL; + } + + /// + // Return the handler for JavaScript dialogs. If no handler is provided the + // default implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetJSDialogHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for keyboard events. + /// + /*--cef()--*/ + virtual CefRefPtr GetKeyboardHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for browser life span events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLifeSpanHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for browser load status events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLoadHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for off-screen rendering events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRenderHandler() OVERRIDE { + return this; + } + + /// + // Return the handler for browser request events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequestHandler() OVERRIDE { + return this; + } + + /// + // Called when a new message is received from a different process. Return true + // if the message was handled or false otherwise. Do not keep a reference to + // or attempt to access the message outside of this callback. + /// + /*--cef()--*/ + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) + OVERRIDE; + + // -------------------------------------------------------------------------- + // CefLifeSpanHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events related to browser life span. The + // methods of this class will be called on the UI thread unless otherwise + // indicated. + /// + + /// + // Called on the IO thread before a new popup window is created. The |browser| + // and |frame| parameters represent the source of the popup request. The + // |target_url| and |target_frame_name| values may be empty if none were + // specified with the request. The |popupFeatures| structure contains + // information about the requested popup window. To allow creation of the + // popup window optionally modify |windowInfo|, |client|, |settings| and + // |no_javascript_access| and return false. To cancel creation of the popup + // window return true. The |client| and |settings| values will default to the + // source browser's values. The |no_javascript_access| value indicates whether + // the new browser window should be scriptable and in the same process as the + // source browser. + /*--cef(optional_param=target_url,optional_param=target_frame_name)--*/ + virtual bool OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) OVERRIDE; + + /// + // Called after a new browser is created. + /// + /*--cef()--*/ + virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; + + /// + // Called when a modal window is about to display and the modal loop should + // begin running. Return false to use the default modal loop implementation or + // true to use a custom implementation. + /// + /*--cef()--*/ + virtual bool RunModal(CefRefPtr browser) OVERRIDE; + + /// + // Called when a browser has recieved a request to close. This may result + // directly from a call to CefBrowserHost::CloseBrowser() or indirectly if the + // browser is a top-level OS window created by CEF and the user attempts to + // close the window. This method will be called after the JavaScript + // 'onunload' event has been fired. It will not be called for browsers after + // the associated OS window has been destroyed (for those browsers it is no + // longer possible to cancel the close). + // + // If CEF created an OS window for the browser returning false will send an OS + // close notification to the browser window's top-level owner (e.g. WM_CLOSE + // on Windows, performClose: on OS-X and "delete_event" on Linux). If no OS + // window exists (window rendering disabled) returning false will cause the + // browser object to be destroyed immediately. Return true if the browser is + // parented to another window and that other window needs to receive close + // notification via some non-standard technique. + // + // If an application provides its own top-level window it should handle OS + // close notifications by calling CefBrowserHost::CloseBrowser(false) instead + // of immediately closing (see the example below). This gives CEF an + // opportunity to process the 'onbeforeunload' event and optionally cancel the + // close before DoClose() is called. + // + // The CefLifeSpanHandler::OnBeforeClose() method will be called immediately + // before the browser object is destroyed. The application should only exit + // after OnBeforeClose() has been called for all existing browsers. + // + // If the browser represents a modal window and a custom modal loop + // implementation was provided in CefLifeSpanHandler::RunModal() this callback + // should be used to restore the opener window to a usable state. + // + // By way of example consider what should happen during window close when the + // browser is parented to an application-provided top-level OS window. + // 1. User clicks the window close button which sends an OS close + // notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and + // "delete_event" on Linux). + // 2. Application's top-level window receives the close notification and: + // A. Calls CefBrowserHost::CloseBrowser(false). + // B. Cancels the window close. + // 3. JavaScript 'onbeforeunload' handler executes and shows the close + // confirmation dialog (which can be overridden via + // CefJSDialogHandler::OnBeforeUnloadDialog()). + // 4. User approves the close. + // 5. JavaScript 'onunload' handler executes. + // 6. Application's DoClose() handler is called. Application will: + // A. Call CefBrowserHost::ParentWindowWillClose() to notify CEF that the + // parent window will be closing. + // B. Set a flag to indicate that the next close attempt will be allowed. + // C. Return false. + // 7. CEF sends an OS close notification. + // 8. Application's top-level window receives the OS close notification and + // allows the window to close based on the flag from #6B. + // 9. Browser OS window is destroyed. + // 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and + // the browser object is destroyed. + // 11. Application exits by calling CefQuitMessageLoop() if no other browsers + // exist. + /// + /*--cef()--*/ + virtual bool DoClose(CefRefPtr browser) OVERRIDE; + + /// + // Called just before a browser is destroyed. Release all references to the + // browser object and do not attempt to execute any methods on the browser + // object after this callback returns. If this is a modal window and a custom + // modal loop implementation was provided in RunModal() this callback should + // be used to exit the custom modal loop. See DoClose() documentation for + // additional usage information. + /// + /*--cef()--*/ + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefDisplayHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events related to browser display state. + // The methods of this class will be called on the UI thread. + /// + + /// + // Called when a frame's address has changed. + /// + /*--cef()--*/ + virtual void OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) OVERRIDE; + + /// + // Called when the page title changes. + /// + /*--cef(optional_param=title)--*/ + virtual void OnTitleChange(CefRefPtr browser, + const CefString& title) OVERRIDE; + + /// + // Called when the browser is about to display a tooltip. |text| contains the + // text that will be displayed in the tooltip. To handle the display of the + // tooltip yourself return true. Otherwise, you can optionally modify |text| + // and then return false to allow the browser to display the tooltip. + // When window rendering is disabled the application is responsible for + // drawing tooltips and the return value is ignored. + /// + /*--cef(optional_param=text)--*/ + virtual bool OnTooltip(CefRefPtr browser, + CefString& text) OVERRIDE; + + /// + // Called when the browser receives a status message. |text| contains the text + // that will be displayed in the status message and |type| indicates the + // status message type. + /// + /*--cef(optional_param=value)--*/ + virtual void OnStatusMessage(CefRefPtr browser, + const CefString& value) OVERRIDE; + + /// + // Called to display a console message. Return true to stop the message from + // being output to the console. + /// + /*--cef(optional_param=message,optional_param=source)--*/ + virtual bool OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefKeyboardHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events related to keyboard input. The + // methods of this class will be called on the UI thread. + /// + + // Called before a keyboard event is sent to the renderer. |event| contains + // information about the keyboard event. |os_event| is the operating system + // event message, if any. Return true if the event was handled or false + // otherwise. If the event will be handled in OnKeyEvent() as a keyboard + // shortcut set |is_keyboard_shortcut| to true and return false. + /*--cef()--*/ + virtual bool OnPreKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event, + bool* is_keyboard_shortcut) OVERRIDE; + + /// + // Called after the renderer and JavaScript in the page has had a chance to + // handle the event. |event| contains information about the keyboard event. + // |os_event| is the operating system event message, if any. Return true if + // the keyboard event was handled or false otherwise. + /// + /*--cef()--*/ + virtual bool OnKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefRequestHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events related to browser requests. The + // methods of this class will be called on the thread indicated. + /// + + /// + // Called on the UI thread before browser navigation. Return true to cancel + // the navigation or false to allow the navigation to proceed. The |request| + // object cannot be modified in this callback. + // CefLoadHandler::OnLoadingStateChange will be called twice in all cases. + // If the navigation is allowed CefLoadHandler::OnLoadStart and + // CefLoadHandler::OnLoadEnd will be called. If the navigation is canceled + // CefLoadHandler::OnLoadError will be called with an |errorCode| value of + // ERR_ABORTED. + /// + /*--cef()--*/ + virtual bool OnBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + bool is_redirect) OVERRIDE; + + /// + // Called on the IO thread before a resource request is loaded. The |request| + // object may be modified. To cancel the request return true otherwise return + // false. + /// + /*--cef()--*/ + virtual bool OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) OVERRIDE; + + /// + // Called on the IO thread before a resource is loaded. To allow the resource + // to load normally return NULL. To specify a handler for the resource return + // a CefResourceHandler object. The |request| object should not be modified in + // this callback. + /// + /*--cef()--*/ + virtual CefRefPtr GetResourceHandler( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) OVERRIDE; + + /// + // Called on the IO thread when a resource load is redirected. The |old_url| + // parameter will contain the old URL. The |new_url| parameter will contain + // the new URL and can be changed if desired. + /// + /*--cef()--*/ + virtual void OnResourceRedirect(CefRefPtr browser, + CefRefPtr frame, + const CefString& old_url, + CefString& new_url) OVERRIDE; + + /// + // Called on the IO thread when the browser needs credentials from the user. + // |isProxy| indicates whether the host is a proxy server. |host| contains the + // hostname and |port| contains the port number. Return true to continue the + // request and call CefAuthCallback::Continue() when the authentication + // information is available. Return false to cancel the request. + /// + /*--cef(optional_param=realm)--*/ + virtual bool GetAuthCredentials(CefRefPtr browser, + CefRefPtr frame, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) + OVERRIDE; + + /// + // Called on the IO thread when JavaScript requests a specific storage quota + // size via the webkitStorageInfo.requestQuota function. |origin_url| is the + // origin of the page making the request. |new_size| is the requested quota + // size in bytes. Return true and call CefQuotaCallback::Continue() either in + // this method or at a later time to grant or deny the request. Return false + // to cancel the request. + /// + /*--cef(optional_param=realm)--*/ + virtual bool OnQuotaRequest(CefRefPtr browser, + const CefString& origin_url, + int64 new_size, + CefRefPtr callback) OVERRIDE; + + /// + // Called on the UI thread to handle requests for URLs with an unknown + // protocol component. Set |allow_os_execution| to true to attempt execution + // via the registered OS protocol handler, if any. + // SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED + // ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. + /// + /*--cef()--*/ + virtual void OnProtocolExecution(CefRefPtr browser, + const CefString& url, + bool& allow_os_execution) OVERRIDE; + + /// + // Called on the browser process IO thread before a plugin is loaded. Return + // true to block loading of the plugin. + /// + /*--cef(optional_param=url,optional_param=policy_url)--*/ + virtual bool OnBeforePluginLoad(CefRefPtr browser, + const CefString& url, + const CefString& policy_url, + CefRefPtr info) OVERRIDE; + + /// + // Called on the UI thread to handle requests for URLs with an invalid + // SSL certificate. Return true and call CefAllowCertificateErrorCallback:: + // Continue() either in this method or at a later time to continue or cancel + // the request. Return false to cancel the request immediately. If |callback| + // is empty the error cannot be recovered from and the request will be + // canceled automatically. If CefSettings.ignore_certificate_errors is set + // all invalid certificates will be accepted without calling this method. + /// + /*--cef()--*/ + virtual bool OnCertificateError( + cef_errorcode_t cert_error, + const CefString& request_url, + CefRefPtr callback) OVERRIDE; + + /// + // Called when the render process terminates unexpectedly. |status| indicates + // how the process terminated. + /// + /*--cef()--*/ + virtual void OnRenderProcessTerminated(CefRefPtr browser, + cef_termination_status_t status) + OVERRIDE; + + /// + // Called when a plugin has crashed. |plugin_path| is the path of the plugin + // that crashed. + /// + /*--cef()--*/ + virtual void OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefLoadHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events related to browser load status. + // The methods of this class will be called on the UI thread. + /// + + /// + // Called when the loading state has changed. + /// + /*--cef()--*/ + virtual void OnLoadingStateChange(CefRefPtr browser, + bool isLoading, + bool canGoBack, + bool canGoForward) OVERRIDE; + + /// + // Called when the browser begins loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // may not be called for a particular frame if the load request for that frame + // fails. + /// + /*--cef()--*/ + virtual void OnLoadStart(CefRefPtr browser, + CefRefPtr frame) OVERRIDE; + + /// + // Called when the browser is done loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // will always be called for all frames irrespective of whether the request + // completes successfully. + /// + /*--cef()--*/ + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) OVERRIDE; + + /// + // Called when the browser fails to load a resource. |errorCode| is the error + // code number, |errorText| is the error text and and |failedUrl| is the URL + // that failed to load. See net\base\net_error_list.h for complete + // descriptions of the error codes. + /// + /*--cef(optional_param=errorText)--*/ + virtual void OnLoadError(CefRefPtr browser, + CefRefPtr frame, + cef_errorcode_t errorCode, + const CefString& errorText, + const CefString& failedUrl) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefRenderHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle events when window rendering is disabled. + // The methods of this class will be called on the UI thread. + /// + + /// + // Called to retrieve the root window rectangle in screen coordinates. Return + // true if the rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetRootScreenRect(CefRefPtr browser, + CefRect& rect) OVERRIDE; + + /// + // Called to retrieve the view rectangle which is relative to screen + // coordinates. Return true if the rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetViewRect(CefRefPtr browser, CefRect& rect) + OVERRIDE; + + /// + // Called to retrieve the translation from view coordinates to actual screen + // coordinates. Return true if the screen coordinates were provided. + /// + /*--cef()--*/ + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) OVERRIDE; + + /// + // Called to allow the client to fill in the CefScreenInfo object with + // appropriate values. Return true if the |screen_info| structure has been + // modified. + // + // If the screen info rectangle is left empty the rectangle from GetViewRect + // will be used. If the rectangle is still empty or invalid popups may not be + // drawn correctly. + /// + /*--cef()--*/ + virtual bool GetScreenInfo(CefRefPtr browser, + CefScreenInfo& screen_info) OVERRIDE; + + /// + // Called when the browser wants to show or hide the popup widget. The popup + // should be shown if |show| is true and hidden if |show| is false. + /// + /*--cef()--*/ + virtual void OnPopupShow(CefRefPtr browser, + bool show) OVERRIDE; + + /// + // Called when the browser wants to move or resize the popup widget. |rect| + // contains the new location and size. + /// + /*--cef()--*/ + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) OVERRIDE; + + /// + // Called when an element should be painted. |type| indicates whether the + // element is the view or the popup widget. |buffer| contains the pixel data + // for the whole image. |dirtyRects| contains the set of rectangles that need + // to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes + // in size and represents a BGRA image with an upper-left origin. + /// + /*--cef()--*/ + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) OVERRIDE; + + /// + // Called when the browser window's cursor has changed. + /// + /*--cef()--*/ + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) OVERRIDE; + + /// + // Called when the scroll offset has changed. + /// + /*--cef()--*/ + virtual void OnScrollOffsetChanged(CefRefPtr browser) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefJSDialogHandler + // -------------------------------------------------------------------------- + typedef cef_jsdialog_type_t JSDialogType; + + /// + // Called to run a JavaScript dialog. The |default_prompt_text| value will be + // specified for prompt dialogs only. Set |suppress_message| to true and + // return false to suppress the message (suppressing messages is preferable + // to immediately executing the callback as this is used to detect presumably + // malicious behavior like spamming alert messages in onbeforeunload). Set + // |suppress_message| to false and return false to use the default + // implementation (the default implementation will show one modal dialog at a + // time and suppress any additional dialog requests until the displayed dialog + // is dismissed). Return true if the application will use a custom dialog or + // if the callback has been executed immediately. Custom dialogs may be either + // modal or modeless. If a custom dialog is used the application must execute + // |callback| once the custom dialog is dismissed. + /// + /*--cef(optional_param=accept_lang,optional_param=message_text, + optional_param=default_prompt_text)--*/ + virtual bool OnJSDialog(CefRefPtr browser, + const CefString& origin_url, + const CefString& accept_lang, + JSDialogType dialog_type, + const CefString& message_text, + const CefString& default_prompt_text, + CefRefPtr callback, + bool& suppress_message) OVERRIDE; + + /// + // Called to run a dialog asking the user if they want to leave a page. Return + // false to use the default dialog implementation. Return true if the + // application will use a custom dialog or if the callback has been executed + // immediately. Custom dialogs may be either modal or modeless. If a custom + // dialog is used the application must execute |callback| once the custom + // dialog is dismissed. + /// + /*--cef(optional_param=message_text)--*/ + virtual bool OnBeforeUnloadDialog(CefRefPtr browser, + const CefString& message_text, + bool is_reload, + CefRefPtr callback) + OVERRIDE; + + /// + // Called to cancel any pending dialogs and reset any saved dialog state. Will + // be called due to events like page navigation irregardless of whether any + // dialogs are currently pending. + /// + /*--cef()--*/ + virtual void OnResetDialogState(CefRefPtr browser) OVERRIDE; + + /// + // Called when the default implementation dialog is closed. + /// + /*--cef()--*/ + virtual void OnDialogClosed(CefRefPtr browser) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefDownloadHandler + // -------------------------------------------------------------------------- + + /// + // Class used to handle file downloads. The methods of this class will called + // on the browser process UI thread. + /// + + /// + // Called before a download begins. |suggested_name| is the suggested name for + // the download file. By default the download will be canceled. Execute + // |callback| either asynchronously or in this method to continue the download + // if desired. Do not keep a reference to |download_item| outside of this + // method. + /// + /*--cef()--*/ + virtual void OnBeforeDownload( + CefRefPtr browser, + CefRefPtr download_item, + const CefString& suggested_name, + CefRefPtr callback) OVERRIDE; + + /// + // Called when a download's status or progress information has been updated. + // This may be called multiple times before and after OnBeforeDownload(). + // Execute |callback| either asynchronously or in this method to cancel the + // download if desired. Do not keep a reference to |download_item| outside of + // this method. + /// + /*--cef()--*/ + virtual void OnDownloadUpdated( + CefRefPtr browser, + CefRefPtr download_item, + CefRefPtr callback) OVERRIDE; + + // -------------------------------------------------------------------------- + // CefDownloadHandler + // -------------------------------------------------------------------------- + + /// + // Implement this interface to handle context menu events. The methods of this + // class will be called on the UI thread. + /// + + typedef cef_event_flags_t EventFlags; + + /// + // Called before a context menu is displayed. |params| provides information + // about the context menu state. |model| initially contains the default + // context menu. The |model| can be cleared to show no context menu or + // modified to show a custom menu. Do not keep references to |params| or + // |model| outside of this callback. + /// + /*--cef()--*/ + virtual void OnBeforeContextMenu(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + CefRefPtr model) OVERRIDE; + + /// + // Called to execute a command selected from the context menu. Return true if + // the command was handled or false for the default implementation. See + // cef_menu_id_t for the command ids that have default implementations. All + // user-defined command ids should be between MENU_ID_USER_FIRST and + // MENU_ID_USER_LAST. |params| will have the same values as what was passed to + // OnBeforeContextMenu(). Do not keep a reference to |params| outside of this + // callback. + /// + /*--cef()--*/ + virtual bool OnContextMenuCommand(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + int command_id, + EventFlags event_flags) OVERRIDE; + + /// + // Called when the context menu is dismissed irregardless of whether the menu + // was empty or a command was selected. + /// + /*--cef()--*/ + virtual void OnContextMenuDismissed(CefRefPtr browser, + CefRefPtr frame) OVERRIDE; + + +private: + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ClientHandler); + + // Include the default locking implementation. + // IMPLEMENT_LOCKING(ClientHandler); + +}; diff --git a/cefpython/cef3/client_handler/client_handler_py27_32bit.vcproj b/cefpython/cef3/client_handler/client_handler_py27_32bit.vcproj new file mode 100644 index 00000000..c8d8051b --- /dev/null +++ b/cefpython/cef3/client_handler/client_handler_py27_32bit.vcproj @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/client_handler/client_handler_py27_64bit.vcproj b/cefpython/cef3/client_handler/client_handler_py27_64bit.vcproj new file mode 100644 index 00000000..a20ce5ac --- /dev/null +++ b/cefpython/cef3/client_handler/client_handler_py27_64bit.vcproj @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/client_handler/client_handler_py34_32bit.vcproj b/cefpython/cef3/client_handler/client_handler_py34_32bit.vcproj new file mode 100644 index 00000000..183f16cb --- /dev/null +++ b/cefpython/cef3/client_handler/client_handler_py34_32bit.vcproj @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/client_handler/cookie_visitor.cpp b/cefpython/cef3/client_handler/cookie_visitor.cpp new file mode 100644 index 00000000..e70c83b5 --- /dev/null +++ b/cefpython/cef3/client_handler/cookie_visitor.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "cookie_visitor.h" +#include + +bool CookieVisitor::Visit( + const CefCookie& cookie, + int count, + int total, + bool& deleteCookie + ) { + REQUIRE_IO_THREAD(); + return CookieVisitor_Visit(cookieVisitorId_, cookie, count, total, + deleteCookie); +} diff --git a/cefpython/cef3/client_handler/cookie_visitor.h b/cefpython/cef3/client_handler/cookie_visitor.h new file mode 100644 index 00000000..b33a8f6e --- /dev/null +++ b/cefpython/cef3/client_handler/cookie_visitor.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class CookieVisitor : public CefCookieVisitor +{ +public: + int cookieVisitorId_; +public: + CookieVisitor(int cookieVisitorId) + : cookieVisitorId_(cookieVisitorId) { + } + + virtual bool Visit( + const CefCookie& cookie, + int count, + int total, + bool& deleteCookie + ) OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(CookieVisitor); +}; diff --git a/cefpython/cef3/client_handler/dpi_aware.cpp b/cefpython/cef3/client_handler/dpi_aware.cpp new file mode 100644 index 00000000..bf3bbf43 --- /dev/null +++ b/cefpython/cef3/client_handler/dpi_aware.cpp @@ -0,0 +1,223 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// Windows only + +#pragma comment(lib, "Gdi32.lib") +#include + +#include "dpi_aware.h" +#include "include/cef_runnable.h" +#include "LOG_DEBUG.h" + +const int DEFAULT_DPIX = 96; + +bool IsProcessDpiAware() { + typedef BOOL(WINAPI *IsProcessDPIAwarePtr)(VOID); + IsProcessDPIAwarePtr is_process_dpi_aware_func = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("user32.dll"), + "IsProcessDPIAware")); + BOOL is_aware = FALSE; + if (is_process_dpi_aware_func) { + is_aware = is_process_dpi_aware_func(); + if (is_aware == TRUE) { + return true; + } + } + // GetProcessDpiAwareness is available only on Win8. So it + // should be called only as a back-up plan after IsProcessDPIAware + // was called. Also if IsProcessDPIAware returned false, + // then GetProcessDpiAwareness is called as well. + if (GetProcessDpiAwareness() != PROCESS_DPI_UNAWARE) { + return true; + } + return false; +} + +PROCESS_DPI_AWARENESS GetProcessDpiAwareness() { + // Win8.1 supports monitor-specific DPI scaling, so it is + // recommended to use GetProcessDPIAwareness instead of the + // deprecated IsProcessDPIAware. + typedef HRESULT(WINAPI *GetProcessDpiAwarenessPtr) + (HANDLE,PROCESS_DPI_AWARENESS*); + GetProcessDpiAwarenessPtr get_process_dpi_awareness_func = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("user32.dll"), + "GetProcessDpiAwarenessInternal")); + if (get_process_dpi_awareness_func) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, + GetCurrentProcessId()); + PROCESS_DPI_AWARENESS result; + HRESULT hr = get_process_dpi_awareness_func(hProcess, &result); + if (SUCCEEDED(hr)) { + return result; + } + // Possible failures include E_INVALIDARG or E_ACCESSDENIED. + LOG_DEBUG << "Browser: GetProcessDpiAwareness failed with HR=" << hr; + } + return PROCESS_DPI_UNAWARE; +} + +void SetProcessDpiAware() { + // Win8.1 supports monitor-specific DPI scaling, so it is + // recommended to use SetProcessDPIAwareness instead of the + // deprecated SetProcessDPIAware. SetProcessDpiAwareness is + // only available on Win8. So as a back-up plan SetProcessDPIAware + // is called. + + // If DPI aware manifest was embedded in executable, or + // "Disable display scaling on high DPI settings" was checked + // on the executable properties (Compatibility tab), then + // DPI awareness is already set. + /* + What if GetProcessDpiAwareness returned + PROCESS_PER_MONITOR_DPI_AWARE? The code below sets awareness + to PROCESS_SYSTEM_DPI_AWARE, so it should be called either way. + --OFF: + if (IsProcessDpiAware()) { + return; + } + */ + + typedef BOOL(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS); + SetProcessDpiAwarenessPtr set_process_dpi_awareness_func = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("user32.dll"), + "SetProcessDpiAwarenessInternal")); + if (set_process_dpi_awareness_func) { + LOG_DEBUG << "Browser: SetProcessDpiAware: " + << "calling user32.dll SetProcessDpiAwareness"; + HRESULT hr = set_process_dpi_awareness_func(PROCESS_SYSTEM_DPI_AWARE); + if (SUCCEEDED(hr)) { + LOG_DEBUG << "Browser: SetBrowserDpiAware: " + "SetProcessDpiAwareness succeeded"; + return; + } else if (hr == E_ACCESSDENIED) { + LOG_DEBUG << "Browser: SetBrowserDpiAware: " + "SetProcessDpiAwareness FAILED: " + "The DPI awareness is already set, either by calling " + "this API previously or through the application (.exe) " + "manifest."; + // Do not return here, let's try to call SetProcessDPIAware. + } else { + LOG_DEBUG << "Browser: SetBrowserDpiAware: " + "SetProcessDpiAwareness FAILED"; + // Do not return here, let's try to call SetProcessDPIAware. + } + } + + // SetProcessDpiAwareness not found in user32.dll or the call failed. + typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID); + SetProcessDPIAwarePtr set_process_dpi_aware_func = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("user32.dll"), + "SetProcessDPIAware")); + if (set_process_dpi_aware_func) { + // If cefpython.Initialize() wasn't yet called, then + // this log message won't be written, as g_debug is + // is set during CEF initialization. + LOG_DEBUG << "Browser: SetProcessDpiAware: " + << "calling user32.dll SetProcessDPIAware"; + set_process_dpi_aware_func(); + } +} + +void GetSystemDpi(int* dpix, int* dpiy) { + // Win7 DPI (Control Panel > Appearance and Personalization > Display): + // text size Larger 150% => dpix/dpiy 144 + // text size Medium 125% => dpix/dpiy 120 + // text size Smaller 100% => dpix/dpiy 96 + // + // DPI settings should not be cached. When SetProcessDpiAware + // is not yet called, then OS returns 96 DPI, even though it + // is set to 144 DPI. After DPI Awareness is enabled for the + // running process it will return the correct 144 DPI. + HDC hdc = GetDC(HWND_DESKTOP); + *dpix = GetDeviceCaps(hdc, LOGPIXELSX); + *dpiy = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(HWND_DESKTOP, hdc); +} + +void GetDpiAwareWindowSize(int* width, int* height) { + int dpix = 0; + int dpiy = 0; + GetSystemDpi(&dpix, &dpiy); + double newZoomLevel = 0.0; + // 1. Using only "dpix" value to calculate zoom level. All + // modern displays have equal horizontal and vertical resolution. + // 2. Calculation for DPI < 96 is not yet supported (newZoomLevel<0.0). + newZoomLevel = (dpix - DEFAULT_DPIX) / 24; + if (newZoomLevel > 0.0) { + *width = *width + (int)ceil(newZoomLevel * 0.25 * (*width)); + *height = *height + (int)ceil(newZoomLevel * 0.25 * (*height)); + LOG_DEBUG << "Browser: GetDpiAwareWindowSize: " + << "enlarged by " << ceil(newZoomLevel * 0.25 * 100) << "% " + << "new size = " << *width << "/" << *height; + } +} + +void SetBrowserDpiSettings(CefRefPtr cefBrowser, + CefString autoZooming) { + // Setting zoom level immediately after browser was created + // won't work. We need to wait a moment before we can set it. + REQUIRE_UI_THREAD(); + + double oldZoomLevel = cefBrowser->GetHost()->GetZoomLevel(); + double newZoomLevel = 0.0; + + int dpix = 0; + int dpiy = 0; + GetSystemDpi(&dpix, &dpiy); + + if (autoZooming.ToString() == "system_dpi") { + // Using only "dpix" value to calculate zoom level. All + // modern displays have equal horizontal/vertical resolution. + // Examples: + // dpix=96 zoom=0.0 + // dpix=120 zoom=1.0 + // dpix=144 zoom=2.0 + // dpix=72 zoom=-1.0 + newZoomLevel = (dpix - DEFAULT_DPIX) / 24; + } else { + // When atof() fails converting string to double, then + // 0.0 is returned. + newZoomLevel = atof(autoZooming.ToString().c_str()); + } + + if (oldZoomLevel != newZoomLevel) { + cefBrowser->GetHost()->SetZoomLevel(newZoomLevel); + if (cefBrowser->GetHost()->GetZoomLevel() != oldZoomLevel) { + // OK succes. + LOG_DEBUG << "Browser: SetBrowserDpiSettings: " + << "DPI=" << dpix << " " + << "zoom=" << cefBrowser->GetHost()->GetZoomLevel(); + } + } else { + // This code block running can also be a result of executing + // SetZoomLevel(), as GetZoomLevel() didn't return the new + // value that was set. Documentation says that if SetZoomLevel + // is called on the UI thread, then GetZoomLevel should + // immediately return the same value that was set. Unfortunately + // this seems not to be true. + static bool already_logged = false; + if (!already_logged) { + already_logged = true; + // OK success. + LOG_DEBUG << "Browser: SetBrowserDpiSettings: " + << "DPI=" << dpix << " " + << "zoom=" << cefBrowser->GetHost()->GetZoomLevel(); + } + } + // We need to check zooming constantly, during loading of pages. + // If we set zooming to 2.0 for localhost/ and then it navigates + // to google.com, then the zomming is back at 0.0 and needs to + // be set again. + CefPostDelayedTask( + TID_UI, + NewCefRunnableFunction(&SetBrowserDpiSettings, cefBrowser, + autoZooming), + 50); +} + diff --git a/cefpython/cef3/client_handler/dpi_aware.h b/cefpython/cef3/client_handler/dpi_aware.h new file mode 100644 index 00000000..7bd5caea --- /dev/null +++ b/cefpython/cef3/client_handler/dpi_aware.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// Windows only + +#pragma once + +#include +#include "include/cef_app.h" +#include "util.h" + +// Duplicated from Win8.1 SDK ShellScalingApi.h +typedef enum PROCESS_DPI_AWARENESS { + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 +} PROCESS_DPI_AWARENESS; + +bool IsProcessDpiAware(); +PROCESS_DPI_AWARENESS GetProcessDpiAwareness(); +void SetProcessDpiAware(); +void GetSystemDpi(int* outx, int* outy); +void GetDpiAwareWindowSize(int* width, int* height); +void SetBrowserDpiSettings(CefRefPtr cefBrowser, + CefString autoZooming); + diff --git a/cefpython/cef3/client_handler/request_context_handler.cpp b/cefpython/cef3/client_handler/request_context_handler.cpp new file mode 100644 index 00000000..dd2d3e16 --- /dev/null +++ b/cefpython/cef3/client_handler/request_context_handler.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "request_context_handler.h" +#include "cefpython_public_api.h" +#include "DebugLog.h" + +// -------------------------------------------------------------------------- +// CefRequestContextHandler +// -------------------------------------------------------------------------- + +/// +// Called on the IO thread to retrieve the cookie manager. Cookies managers +// can be unique per browser or shared across multiple browsers. +// The global cookie manager will be used if this method returns NULL. +/// +/*--cef()--*/ +CefRefPtr RequestContextHandler::GetCookieManager() { + REQUIRE_IO_THREAD(); + if (browser_.get()) { + return RequestHandler_GetCookieManager(browser_, + browser_->GetMainFrame()->GetURL()); + } else { + CefString mainUrl; + return RequestHandler_GetCookieManager(browser_, mainUrl); + } + // Default: return NULL. +} diff --git a/cefpython/cef3/client_handler/request_context_handler.h b/cefpython/cef3/client_handler/request_context_handler.h new file mode 100644 index 00000000..317f0b6b --- /dev/null +++ b/cefpython/cef3/client_handler/request_context_handler.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class RequestContextHandler : + public CefRequestContextHandler +{ +public: + // Browser may be NULL when instantiated from cefpython.CreateBrowserSync. + // In such case SetBrowser will be called after browser creation. + // GetCookieManager must handle a case when browser is NULL. + explicit RequestContextHandler(CefRefPtr browser) + : browser_(browser) { + } + + void SetBrowser(CefRefPtr browser) { + browser_ = browser; + } + + /// + // Called on the IO thread to retrieve the cookie manager. Cookies managers + // can be unique per browser or shared across multiple browsers. + // The global cookie manager will be used if this method returns NULL. + /// + /*--cef()--*/ + virtual CefRefPtr GetCookieManager() OVERRIDE; + +private: + CefRefPtr browser_; + +private: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ClientHandler); +}; diff --git a/cefpython/cef3/client_handler/resource_handler.cpp b/cefpython/cef3/client_handler/resource_handler.cpp new file mode 100644 index 00000000..d7229276 --- /dev/null +++ b/cefpython/cef3/client_handler/resource_handler.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "resource_handler.h" + +/// +// Begin processing the request. To handle the request return true and call +// CefCallback::Continue() once the response header information is available +// (CefCallback::Continue() can also be called from inside this method if +// header information is available immediately). To cancel the request return +// false. +/// +/*--cef()--*/ +bool ResourceHandler::ProcessRequest(CefRefPtr request, + CefRefPtr callback) { + REQUIRE_IO_THREAD(); + return ResourceHandler_ProcessRequest(resourceHandlerId_, request, + callback); +} + +/// +// Retrieve response header information. If the response length is not known +// set |response_length| to -1 and ReadResponse() will be called until it +// returns false. If the response length is known set |response_length| +// to a positive value and ReadResponse() will be called until it returns +// false or the specified number of bytes have been read. Use the |response| +// object to set the mime type, http status code and other optional header +// values. To redirect the request to a new URL set |redirectUrl| to the new +// URL. +/// +/*--cef()--*/ +void ResourceHandler::GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) { + REQUIRE_IO_THREAD(); + ResourceHandler_GetResponseHeaders(resourceHandlerId_, response, + response_length, redirectUrl); +} + +/// +// Read response data. If data is available immediately copy up to +// |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of +// bytes copied, and return true. To read the data at a later time set +// |bytes_read| to 0, return true and call CefCallback::Continue() when the +// data is available. To indicate response completion return false. +/// +/*--cef()--*/ +bool ResourceHandler::ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) { + REQUIRE_IO_THREAD(); + return ResourceHandler_ReadResponse(resourceHandlerId_, data_out, + bytes_to_read, bytes_read, callback); +} + +/// +// Return true if the specified cookie can be sent with the request or false +// otherwise. If false is returned for any cookie then no cookies will be sent +// with the request. +/// +/*--cef()--*/ +bool ResourceHandler::CanGetCookie(const CefCookie& cookie) { + REQUIRE_IO_THREAD(); + return ResourceHandler_CanGetCookie(resourceHandlerId_, cookie); +} + +/// +// Return true if the specified cookie returned with the response can be set +// or false otherwise. +/// +/*--cef()--*/ +bool ResourceHandler::CanSetCookie(const CefCookie& cookie) { + REQUIRE_IO_THREAD(); + return ResourceHandler_CanSetCookie(resourceHandlerId_, cookie); +} + +/// +// Request processing has been canceled. +/// +/*--cef()--*/ +void ResourceHandler::Cancel() { + REQUIRE_IO_THREAD(); + return ResourceHandler_Cancel(resourceHandlerId_); +} diff --git a/cefpython/cef3/client_handler/resource_handler.h b/cefpython/cef3/client_handler/resource_handler.h new file mode 100644 index 00000000..d1ac37b6 --- /dev/null +++ b/cefpython/cef3/client_handler/resource_handler.h @@ -0,0 +1,85 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class ResourceHandler : public CefResourceHandler +{ +public: + int resourceHandlerId_; +public: + ResourceHandler(int resourceHandlerId) + : resourceHandlerId_(resourceHandlerId) { + } + + /// + // Begin processing the request. To handle the request return true and call + // CefCallback::Continue() once the response header information is available + // (CefCallback::Continue() can also be called from inside this method if + // header information is available immediately). To cancel the request return + // false. + /// + /*--cef()--*/ + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) OVERRIDE; + + /// + // Retrieve response header information. If the response length is not known + // set |response_length| to -1 and ReadResponse() will be called until it + // returns false. If the response length is known set |response_length| + // to a positive value and ReadResponse() will be called until it returns + // false or the specified number of bytes have been read. Use the |response| + // object to set the mime type, http status code and other optional header + // values. To redirect the request to a new URL set |redirectUrl| to the new + // URL. + /// + /*--cef()--*/ + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) OVERRIDE; + + /// + // Read response data. If data is available immediately copy up to + // |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of + // bytes copied, and return true. To read the data at a later time set + // |bytes_read| to 0, return true and call CefCallback::Continue() when the + // data is available. To indicate response completion return false. + /// + /*--cef()--*/ + virtual bool ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) OVERRIDE; + + /// + // Return true if the specified cookie can be sent with the request or false + // otherwise. If false is returned for any cookie then no cookies will be sent + // with the request. + /// + /*--cef()--*/ + virtual bool CanGetCookie(const CefCookie& cookie) OVERRIDE; + + /// + // Return true if the specified cookie returned with the response can be set + // or false otherwise. + /// + /*--cef()--*/ + virtual bool CanSetCookie(const CefCookie& cookie) OVERRIDE; + + /// + // Request processing has been canceled. + /// + /*--cef()--*/ + virtual void Cancel() OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ResourceHandler); +}; diff --git a/cefpython/cef3/client_handler/string_visitor.cpp b/cefpython/cef3/client_handler/string_visitor.cpp new file mode 100644 index 00000000..d8f368f0 --- /dev/null +++ b/cefpython/cef3/client_handler/string_visitor.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "string_visitor.h" +#include + +void StringVisitor::Visit( + const CefString& string + ) { + StringVisitor_Visit(stringVisitorId_, string); +} diff --git a/cefpython/cef3/client_handler/string_visitor.h b/cefpython/cef3/client_handler/string_visitor.h new file mode 100644 index 00000000..adec9e5b --- /dev/null +++ b/cefpython/cef3/client_handler/string_visitor.h @@ -0,0 +1,29 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class StringVisitor : public CefStringVisitor +{ +public: + int stringVisitorId_; +public: + StringVisitor(int stringVisitorId) + : stringVisitorId_(stringVisitorId) { + } + + virtual void Visit( + const CefString& string + ) OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(StringVisitor); +}; diff --git a/cefpython/cef3/client_handler/task.cpp b/cefpython/cef3/client_handler/task.cpp new file mode 100644 index 00000000..d5b35b47 --- /dev/null +++ b/cefpython/cef3/client_handler/task.cpp @@ -0,0 +1,17 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "task.h" +#include "include/cef_runnable.h" + +void PostTaskWrapper(int threadId, int taskId) { + // Calling CefPostDelayedTask with 0ms delay seems to give + // better responsiveness than CefPostTask. In wxpython.py + // on Windows the freeze when creating popup window feels + // shorter, when compared to a call to CefPostTask. + CefPostDelayedTask( + static_cast(threadId), + NewCefRunnableFunction(&PyTaskRunnable, taskId), + 0); +} diff --git a/cefpython/cef3/client_handler/task.h b/cefpython/cef3/client_handler/task.h new file mode 100644 index 00000000..c3a4ca66 --- /dev/null +++ b/cefpython/cef3/client_handler/task.h @@ -0,0 +1,8 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include "cefpython_public_api.h" + +void PostTaskWrapper(int threadId, int taskId); diff --git a/cefpython/cef3/client_handler/util_mac.h b/cefpython/cef3/client_handler/util_mac.h new file mode 100644 index 00000000..5641a120 --- /dev/null +++ b/cefpython/cef3/client_handler/util_mac.h @@ -0,0 +1,14 @@ +// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEFPYTHON_UTIL_MAC_H_ +#define CEFPYTHON_UTIL_MAC_H_ + +#include +#include "include/cef_base.h" +#include "include/cef_app.h" + +void MacInitialize(); + +#endif // CEFPYTHON_UTIL_MAC_H_ diff --git a/cefpython/cef3/client_handler/util_mac.mm b/cefpython/cef3/client_handler/util_mac.mm new file mode 100644 index 00000000..c0adfa09 --- /dev/null +++ b/cefpython/cef3/client_handler/util_mac.mm @@ -0,0 +1,66 @@ +// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#import "util_mac.h" +#import +#include +#include "include/cef_app.h" +#include "include/cef_application_mac.h" + +namespace { + +BOOL g_handling_send_event = false; + +} // namespace + +// Add the necessary CrAppControlProtocol +// functionality to NSApplication using categories and swizzling. +@interface NSApplication (CEFPythonApplication) + +- (BOOL)isHandlingSendEvent; +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent; +- (void)_swizzled_sendEvent:(NSEvent*)event; +- (void)_swizzled_terminate:(id)sender; + +@end + +@implementation NSApplication (CEFPythonApplication) + +// This selector is called very early during the application initialization. ++ (void)load { + // Swap NSApplication::sendEvent with _swizzled_sendEvent. + Method original = class_getInstanceMethod(self, @selector(sendEvent)); + Method swizzled = + class_getInstanceMethod(self, @selector(_swizzled_sendEvent)); + method_exchangeImplementations(original, swizzled); + + Method originalTerm = class_getInstanceMethod(self, @selector(terminate:)); + Method swizzledTerm = + class_getInstanceMethod(self, @selector(_swizzled_terminate:)); + method_exchangeImplementations(originalTerm, swizzledTerm); +} + +- (BOOL)isHandlingSendEvent { + return g_handling_send_event; +} + +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent { + g_handling_send_event = handlingSendEvent; +} + +- (void)_swizzled_sendEvent:(NSEvent*)event { + CefScopedSendingEvent sendingEventScoper; + // Calls NSApplication::sendEvent due to the swizzling. + [self _swizzled_sendEvent:event]; +} + +- (void)_swizzled_terminate:(id)sender { + [self _swizzled_terminate:sender]; +} + +@end + +void MacInitialize() { + [NSApplication sharedApplication]; +} diff --git a/cefpython/cef3/client_handler/web_request_client.cpp b/cefpython/cef3/client_handler/web_request_client.cpp new file mode 100644 index 00000000..b7eef1f7 --- /dev/null +++ b/cefpython/cef3/client_handler/web_request_client.cpp @@ -0,0 +1,78 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "web_request_client.h" + +/// +// Interface that should be implemented by the CefURLRequest client. The +// methods of this class will be called on the same thread that created the +// request. +/// + +/// +// Notifies the client that the request has completed. Use the +// CefURLRequest::GetRequestStatus method to determine if the request was +// successful or not. +/// +/*--cef()--*/ +void WebRequestClient::OnRequestComplete(CefRefPtr request) { + WebRequestClient_OnRequestComplete(webRequestId_, request); +} + +/// +// Notifies the client of upload progress. |current| denotes the number of +// bytes sent so far and |total| is the total size of uploading data (or -1 if +// chunked upload is enabled). This method will only be called if the +// UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request. +/// +/*--cef()--*/ +void WebRequestClient::OnUploadProgress(CefRefPtr request, + uint64 current, + uint64 total) { + WebRequestClient_OnUploadProgress(webRequestId_, request, current, total); +} + +/// +// Notifies the client of download progress. |current| denotes the number of +// bytes received up to the call and |total| is the expected total size of the +// response (or -1 if not determined). +/// +/*--cef()--*/ +void WebRequestClient::OnDownloadProgress(CefRefPtr request, + uint64 current, + uint64 total) { + WebRequestClient_OnDownloadProgress(webRequestId_, request, current, + total); +} + +/// +// Called when some part of the response is read. |data| contains the current +// bytes received since the last call. This method will not be called if the +// UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request. +/// +/*--cef()--*/ +void WebRequestClient::OnDownloadData(CefRefPtr request, + const void* data, + size_t data_length) { + WebRequestClient_OnDownloadData(webRequestId_, request, data, data_length); +} + +/// +// Called on the IO thread when the browser needs credentials from the user. +// |isProxy| indicates whether the host is a proxy server. |host| contains the +// hostname and |port| contains the port number. Return true to continue the +// request and call CefAuthCallback::Continue() when the authentication +// information is available. Return false to cancel the request. This method +// will only be called for requests initiated from the browser process. +/// +/*--cef(optional_param=realm)--*/ +bool WebRequestClient::GetAuthCredentials(bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) { + // Not yet implemented. + return false; +} diff --git a/cefpython/cef3/client_handler/web_request_client.h b/cefpython/cef3/client_handler/web_request_client.h new file mode 100644 index 00000000..5c58ad7a --- /dev/null +++ b/cefpython/cef3/client_handler/web_request_client.h @@ -0,0 +1,87 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +#if defined(_WIN32) +#include "../windows/stdint.h" +#endif + +#include "cefpython_public_api.h" + +class WebRequestClient : public CefURLRequestClient +{ +public: + int webRequestId_; +public: + WebRequestClient(int webRequestId) : + webRequestId_(webRequestId) { + } + virtual ~WebRequestClient(){} + + /// + // Interface that should be implemented by the CefURLRequest client. The + // methods of this class will be called on the same thread that created the + // request. + /// + + /// + // Notifies the client that the request has completed. Use the + // CefURLRequest::GetRequestStatus method to determine if the request was + // successful or not. + /// + /*--cef()--*/ + virtual void OnRequestComplete(CefRefPtr request) OVERRIDE; + + /// + // Notifies the client of upload progress. |current| denotes the number of + // bytes sent so far and |total| is the total size of uploading data (or -1 if + // chunked upload is enabled). This method will only be called if the + // UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request. + /// + /*--cef()--*/ + virtual void OnUploadProgress(CefRefPtr request, + uint64 current, + uint64 total) OVERRIDE; + + /// + // Notifies the client of download progress. |current| denotes the number of + // bytes received up to the call and |total| is the expected total size of the + // response (or -1 if not determined). + /// + /*--cef()--*/ + virtual void OnDownloadProgress(CefRefPtr request, + uint64 current, + uint64 total) OVERRIDE; + + /// + // Called when some part of the response is read. |data| contains the current + // bytes received since the last call. This method will not be called if the + // UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request. + /// + /*--cef()--*/ + virtual void OnDownloadData(CefRefPtr request, + const void* data, + size_t data_length) OVERRIDE; + + /// + // Called on the IO thread when the browser needs credentials from the user. + // |isProxy| indicates whether the host is a proxy server. |host| contains the + // hostname and |port| contains the port number. Return true to continue the + // request and call CefAuthCallback::Continue() when the authentication + // information is available. Return false to cancel the request. This method + // will only be called for requests initiated from the browser process. + /// + /*--cef(optional_param=realm)--*/ + virtual bool GetAuthCredentials(bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) OVERRIDE; + +protected: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(WebRequestClient); +}; diff --git a/cefpython/cef3/include/cef_app.h b/cefpython/cef3/include/cef_app.h new file mode 100644 index 00000000..5fd477b9 --- /dev/null +++ b/cefpython/cef3/include/cef_app.h @@ -0,0 +1,182 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_APP_H_ +#define CEF_INCLUDE_CEF_APP_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser_process_handler.h" +#include "include/cef_command_line.h" +#include "include/cef_render_process_handler.h" +#include "include/cef_resource_bundle_handler.h" +#include "include/cef_scheme.h" + +class CefApp; + +/// +// This function should be called from the application entry point function to +// execute a secondary process. It can be used to run secondary processes from +// the browser client executable (default behavior) or from a separate +// executable specified by the CefSettings.browser_subprocess_path value. If +// called for the browser process (identified by no "type" command-line value) +// it will return immediately with a value of -1. If called for a recognized +// secondary process it will block until the process should exit and then return +// the process exit code. The |application| parameter may be empty. +/// +/*--cef(api_hash_check,optional_param=application)--*/ +int CefExecuteProcess(const CefMainArgs& args, CefRefPtr application); + +/// +// This function should be called on the main application thread to initialize +// the CEF browser process. The |application| parameter may be empty. A return +// value of true indicates that it succeeded and false indicates that it failed. +/// +/*--cef(api_hash_check,optional_param=application)--*/ +bool CefInitialize(const CefMainArgs& args, const CefSettings& settings, + CefRefPtr application); + +/// +// This function should be called on the main application thread to shut down +// the CEF browser process before the application exits. +/// +/*--cef()--*/ +void CefShutdown(); + +/// +// Perform a single iteration of CEF message loop processing. This function is +// used to integrate the CEF message loop into an existing application message +// loop. Care must be taken to balance performance against excessive CPU usage. +// This function should only be called on the main application thread and only +// if CefInitialize() is called with a CefSettings.multi_threaded_message_loop +// value of false. This function will not block. +/// +/*--cef()--*/ +void CefDoMessageLoopWork(); + +/// +// Run the CEF message loop. Use this function instead of an application- +// provided message loop to get the best balance between performance and CPU +// usage. This function should only be called on the main application thread and +// only if CefInitialize() is called with a +// CefSettings.multi_threaded_message_loop value of false. This function will +// block until a quit message is received by the system. +/// +/*--cef()--*/ +void CefRunMessageLoop(); + +/// +// Quit the CEF message loop that was started by calling CefRunMessageLoop(). +// This function should only be called on the main application thread and only +// if CefRunMessageLoop() was used. +/// +/*--cef()--*/ +void CefQuitMessageLoop(); + +/// +// Set to true before calling Windows APIs like TrackPopupMenu that enter a +// modal message loop. Set to false after exiting the modal message loop. +/// +/*--cef()--*/ +void CefSetOSModalLoop(bool osModalLoop); + +/// +// Implement this interface to provide handler implementations. Methods will be +// called by the process and/or thread indicated. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefApp : public virtual CefBase { + public: + /// + // Provides an opportunity to view and/or modify command-line arguments before + // processing by CEF and Chromium. The |process_type| value will be empty for + // the browser process. Do not keep a reference to the CefCommandLine object + // passed to this method. The CefSettings.command_line_args_disabled value + // can be used to start with an empty command-line object. Any values + // specified in CefSettings that equate to command-line arguments will be set + // before this method is called. Be cautious when using this method to modify + // command-line arguments for non-browser processes as this may result in + // undefined behavior including crashes. + /// + /*--cef(optional_param=process_type)--*/ + virtual void OnBeforeCommandLineProcessing( + const CefString& process_type, + CefRefPtr command_line) { + } + + /// + // Provides an opportunity to register custom schemes. Do not keep a reference + // to the |registrar| object. This method is called on the main thread for + // each process and the registered schemes should be the same across all + // processes. + /// + /*--cef()--*/ + virtual void OnRegisterCustomSchemes( + CefRefPtr registrar) { + } + + /// + // Return the handler for resource bundle events. If + // CefSettings.pack_loading_disabled is true a handler must be returned. If no + // handler is returned resources will be loaded from pack files. This method + // is called by the browser and render processes on multiple threads. + /// + /*--cef()--*/ + virtual CefRefPtr GetResourceBundleHandler() { + return NULL; + } + + /// + // Return the handler for functionality specific to the browser process. This + // method is called on multiple threads in the browser process. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowserProcessHandler() { + return NULL; + } + + /// + // Return the handler for functionality specific to the render process. This + // method is called on the render process main thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetRenderProcessHandler() { + return NULL; + } +}; + +#endif // CEF_INCLUDE_CEF_APP_H_ diff --git a/cefpython/cef3/include/cef_application_mac.h b/cefpython/cef3/include/cef_application_mac.h new file mode 100644 index 00000000..b4e85db2 --- /dev/null +++ b/cefpython/cef3/include/cef_application_mac.h @@ -0,0 +1,200 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_CEF_APPLICATION_MAC_H_ +#define CEF_INCLUDE_CEF_APPLICATION_MAC_H_ +#pragma once + +#include "include/cef_base.h" + +#if defined(OS_MACOSX) && defined(__OBJC__) + +#ifdef BUILDING_CEF_SHARED + +// Use the existing CrAppControlProtocol definition. +#import "base/mac/scoped_sending_event.h" + +// Use the existing CrAppProtocol definition. +#import "base/message_loop/message_pump_mac.h" + +// Use the existing UnderlayableSurface definition. +#import "ui/base/cocoa/underlay_opengl_hosting_window.h" + +// Use the existing empty protocol definitions. +#import "base/mac/cocoa_protocols.h" + +// Use the existing empty protocol definitions. +#import "base/mac/sdk_forward_declarations.h" + +#else // BUILDING_CEF_SHARED + +#import +#import + +// Copy of definition from base/message_loop/message_pump_mac.h. +@protocol CrAppProtocol +// Must return true if -[NSApplication sendEvent:] is currently on the stack. +- (BOOL)isHandlingSendEvent; +@end + +// Copy of definition from base/mac/scoped_sending_event.h. +@protocol CrAppControlProtocol +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent; +@end + +// Copy of definition from ui/base/cocoa/underlay_opengl_hosting_window.h. +// Common base class for windows that host a OpenGL surface that renders under +// the window. Contains methods relating to hole punching so that the OpenGL +// surface is visible through the window. +@interface UnderlayOpenGLHostingWindow : NSWindow +@end + +// Copy of definitions from base/mac/sdk_forward_declarations.h. +// Forward declarations for APIs that are part of the 10.7 SDK. This will allow +// using them when building with the 10.6 SDK. + +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +enum { + NSEventPhaseNone = 0, // event not associated with a phase. + NSEventPhaseBegan = 0x1 << 0, + NSEventPhaseStationary = 0x1 << 1, + NSEventPhaseChanged = 0x1 << 2, + NSEventPhaseEnded = 0x1 << 3, + NSEventPhaseCancelled = 0x1 << 4, +}; +typedef NSUInteger NSEventPhase; + +@interface NSEvent (LionSDK) ++ (BOOL)isSwipeTrackingFromScrollEventsEnabled; + +- (NSEventPhase)phase; +- (CGFloat)scrollingDeltaX; +- (CGFloat)scrollingDeltaY; +- (BOOL)isDirectionInvertedFromDevice; +@end + +@interface NSScreen (LionSDK) +- (CGFloat)backingScaleFactor; +- (NSRect)convertRectToBacking:(NSRect)aRect; +@end + +@interface NSWindow (LionSDK) +- (CGFloat)backingScaleFactor; +@end + +#endif // MAC_OS_X_VERSION_10_7 + +// The Mac OS X 10.6 SDK introduced new protocols used for delegates. These +// protocol defintions were not present in earlier releases of the Mac OS X +// SDK. In order to support building against the new SDK, which requires +// delegates to conform to these protocols, and earlier SDKs, which do not +// define these protocols at all, this file will provide empty protocol +// definitions when used with earlier SDK versions. + +#if !defined(MAC_OS_X_VERSION_10_6) || \ +MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + +#define DEFINE_EMPTY_PROTOCOL(p) \ +@protocol p \ +@end + +DEFINE_EMPTY_PROTOCOL(NSAlertDelegate) +DEFINE_EMPTY_PROTOCOL(NSApplicationDelegate) +DEFINE_EMPTY_PROTOCOL(NSControlTextEditingDelegate) +DEFINE_EMPTY_PROTOCOL(NSMatrixDelegate) +DEFINE_EMPTY_PROTOCOL(NSMenuDelegate) +DEFINE_EMPTY_PROTOCOL(NSOpenSavePanelDelegate) +DEFINE_EMPTY_PROTOCOL(NSOutlineViewDataSource) +DEFINE_EMPTY_PROTOCOL(NSOutlineViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSSpeechSynthesizerDelegate) +DEFINE_EMPTY_PROTOCOL(NSSplitViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSTableViewDataSource) +DEFINE_EMPTY_PROTOCOL(NSTableViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSTextFieldDelegate) +DEFINE_EMPTY_PROTOCOL(NSTextViewDelegate) +DEFINE_EMPTY_PROTOCOL(NSWindowDelegate) + +#undef DEFINE_EMPTY_PROTOCOL + +#endif + +#endif // BUILDING_CEF_SHARED + +// Forward declarations for APIs that are part of the 10.7 SDK. This will allow +// using them when building with the 10.6 SDK. + +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSView (NSOpenGLSurfaceResolutionLionAPI) +- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; +@end + +@interface NSView (LionAPI) +- (NSSize)convertSizeToBacking:(NSSize)aSize; +- (NSRect)convertRectToBacking:(NSRect)aRect; +- (NSRect)convertRectFromBacking:(NSRect)aRect; +@end + +static NSString* const NSWindowDidChangeBackingPropertiesNotification = + @"NSWindowDidChangeBackingPropertiesNotification"; +static NSString* const NSBackingPropertyOldScaleFactorKey = + @"NSBackingPropertyOldScaleFactorKey"; + +#endif // MAC_OS_X_VERSION_10_7 + +// All CEF client applications must subclass NSApplication and implement this +// protocol. +@protocol CefAppProtocol +@end + +// Controls the state of |isHandlingSendEvent| in the event loop so that it is +// reset properly. +class CefScopedSendingEvent { + public: + CefScopedSendingEvent() + : app_(static_cast*>( + [NSApplication sharedApplication])), + handling_([app_ isHandlingSendEvent]) { + [app_ setHandlingSendEvent:YES]; + } + ~CefScopedSendingEvent() { + [app_ setHandlingSendEvent:handling_]; + } + + private: + NSApplication* app_; + BOOL handling_; +}; + +#endif // defined(OS_MACOSX) && defined(__OBJC__) + +#endif // CEF_INCLUDE_CEF_APPLICATION_MAC_H_ diff --git a/cefpython/cef3/include/cef_auth_callback.h b/cefpython/cef3/include/cef_auth_callback.h new file mode 100644 index 00000000..86d249ad --- /dev/null +++ b/cefpython/cef3/include/cef_auth_callback.h @@ -0,0 +1,64 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ +#define CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Callback interface used for asynchronous continuation of authentication +// requests. +/// +/*--cef(source=library)--*/ +class CefAuthCallback : public virtual CefBase { + public: + /// + // Continue the authentication request. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(const CefString& username, + const CefString& password) =0; + + /// + // Cancel the authentication request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +#endif // CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ diff --git a/cefpython/cef3/include/cef_base.h b/cefpython/cef3/include/cef_base.h new file mode 100644 index 00000000..bc284f72 --- /dev/null +++ b/cefpython/cef3/include/cef_base.h @@ -0,0 +1,154 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_BASE_H_ +#define CEF_INCLUDE_CEF_BASE_H_ +#pragma once + +#include "include/internal/cef_build.h" +#include "include/internal/cef_ptr.h" +#include "include/internal/cef_types_wrappers.h" + +// Bring in platform-specific definitions. +#if defined(OS_WIN) +#include "include/internal/cef_win.h" +#elif defined(OS_MACOSX) +#include "include/internal/cef_mac.h" +#elif defined(OS_LINUX) +#include "include/internal/cef_linux.h" +#endif + +/// +// Interface defining the reference count implementation methods. All framework +// classes must extend the CefBase class. +/// +class CefBase { + public: + /// + // The AddRef method increments the reference count for the object. It should + // be called for every new copy of a pointer to a given object. The resulting + // reference count value is returned and should be used for diagnostic/testing + // purposes only. + /// + virtual int AddRef() =0; + + /// + // The Release method decrements the reference count for the object. If the + // reference count on the object falls to 0, then the object should free + // itself from memory. The resulting reference count value is returned and + // should be used for diagnostic/testing purposes only. + /// + virtual int Release() =0; + + /// + // Return the current number of references. + /// + virtual int GetRefCt() =0; + + protected: + virtual ~CefBase() {} +}; + + +/// +// Class that implements atomic reference counting. +/// +class CefRefCount { + public: + CefRefCount() : refct_(0) {} + + /// + // Atomic reference increment. + /// + int AddRef() { + return CefAtomicIncrement(&refct_); + } + + /// + // Atomic reference decrement. Delete the object when no references remain. + /// + int Release() { + return CefAtomicDecrement(&refct_); + } + + /// + // Return the current number of references. + /// + int GetRefCt() { return refct_; } + + private: + long refct_; // NOLINT(runtime/int) +}; + +/// +// Macro that provides a reference counting implementation for classes extending +// CefBase. +/// +#define IMPLEMENT_REFCOUNTING(ClassName) \ + public: \ + int AddRef() { return refct_.AddRef(); } \ + int Release() { \ + int retval = refct_.Release(); \ + if (retval == 0) \ + delete this; \ + return retval; \ + } \ + int GetRefCt() { return refct_.GetRefCt(); } \ + private: \ + CefRefCount refct_; + +/// +// Macro that provides a locking implementation. Use the Lock() and Unlock() +// methods to protect a section of code from simultaneous access by multiple +// threads. The AutoLock class is a helper that will hold the lock while in +// scope. +/// +#define IMPLEMENT_LOCKING(ClassName) \ + public: \ + class AutoLock { \ + public: \ + explicit AutoLock(ClassName* base) : base_(base) { base_->Lock(); } \ + ~AutoLock() { base_->Unlock(); } \ + private: \ + ClassName* base_; \ + }; \ + void Lock() { critsec_.Lock(); } \ + void Unlock() { critsec_.Unlock(); } \ + private: \ + CefCriticalSection critsec_; + +#endif // CEF_INCLUDE_CEF_BASE_H_ diff --git a/cefpython/cef3/include/cef_browser.h b/cefpython/cef3/include/cef_browser.h new file mode 100644 index 00000000..50f7fb25 --- /dev/null +++ b/cefpython/cef3/include/cef_browser.h @@ -0,0 +1,513 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_BROWSER_H_ +#define CEF_INCLUDE_CEF_BROWSER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_frame.h" +#include "include/cef_process_message.h" +#include "include/cef_request_context.h" +#include + +class CefBrowserHost; +class CefClient; + + +/// +// Class used to represent a browser window. When used in the browser process +// the methods of this class may be called on any thread unless otherwise +// indicated in the comments. When used in the render process the methods of +// this class may only be called on the main thread. +/// +/*--cef(source=library)--*/ +class CefBrowser : public virtual CefBase { + public: + /// + // Returns the browser host object. This method can only be called in the + // browser process. + /// + /*--cef()--*/ + virtual CefRefPtr GetHost() =0; + + /// + // Returns true if the browser can navigate backwards. + /// + /*--cef()--*/ + virtual bool CanGoBack() =0; + + /// + // Navigate backwards. + /// + /*--cef()--*/ + virtual void GoBack() =0; + + /// + // Returns true if the browser can navigate forwards. + /// + /*--cef()--*/ + virtual bool CanGoForward() =0; + + /// + // Navigate forwards. + /// + /*--cef()--*/ + virtual void GoForward() =0; + + /// + // Returns true if the browser is currently loading. + /// + /*--cef()--*/ + virtual bool IsLoading() =0; + + /// + // Reload the current page. + /// + /*--cef()--*/ + virtual void Reload() =0; + + /// + // Reload the current page ignoring any cached data. + /// + /*--cef()--*/ + virtual void ReloadIgnoreCache() =0; + + /// + // Stop loading the page. + /// + /*--cef()--*/ + virtual void StopLoad() =0; + + /// + // Returns the globally unique identifier for this browser. + /// + /*--cef()--*/ + virtual int GetIdentifier() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Returns true if the window is a popup window. + /// + /*--cef()--*/ + virtual bool IsPopup() =0; + + /// + // Returns true if a document has been loaded in the browser. + /// + /*--cef()--*/ + virtual bool HasDocument() =0; + + /// + // Returns the main (top-level) frame for the browser window. + /// + /*--cef()--*/ + virtual CefRefPtr GetMainFrame() =0; + + /// + // Returns the focused frame for the browser window. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusedFrame() =0; + + /// + // Returns the frame with the specified identifier, or NULL if not found. + /// + /*--cef(capi_name=get_frame_byident)--*/ + virtual CefRefPtr GetFrame(int64 identifier) =0; + + /// + // Returns the frame with the specified name, or NULL if not found. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame(const CefString& name) =0; + + /// + // Returns the number of frames that currently exist. + /// + /*--cef()--*/ + virtual size_t GetFrameCount() =0; + + /// + // Returns the identifiers of all existing frames. + /// + /*--cef(count_func=identifiers:GetFrameCount)--*/ + virtual void GetFrameIdentifiers(std::vector& identifiers) =0; + + /// + // Returns the names of all existing frames. + /// + /*--cef()--*/ + virtual void GetFrameNames(std::vector& names) =0; + + // + // Send a message to the specified |target_process|. Returns true if the + // message was sent successfully. + /// + /*--cef()--*/ + virtual bool SendProcessMessage(CefProcessId target_process, + CefRefPtr message) =0; +}; + + +/// +// Callback interface for CefBrowserHost::RunFileDialog. The methods of this +// class will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefRunFileDialogCallback : public virtual CefBase { + public: + /// + // Called asynchronously after the file dialog is dismissed. If the selection + // was successful |file_paths| will be a single value or a list of values + // depending on the dialog mode. If the selection was cancelled |file_paths| + // will be empty. + /// + /*--cef(capi_name=cont)--*/ + virtual void OnFileDialogDismissed( + CefRefPtr browser_host, + const std::vector& file_paths) =0; +}; + + +/// +// Class used to represent the browser process aspects of a browser window. The +// methods of this class can only be called in the browser process. They may be +// called on any thread in that process unless otherwise indicated in the +// comments. +/// +/*--cef(source=library)--*/ +class CefBrowserHost : public virtual CefBase { + public: + typedef cef_file_dialog_mode_t FileDialogMode; + typedef cef_mouse_button_type_t MouseButtonType; + typedef cef_paint_element_type_t PaintElementType; + + /// + // Create a new browser window using the window parameters specified by + // |windowInfo|. All values will be copied internally and the actual window + // will be created on the UI thread. If |request_context| is empty the + // global request context will be used. This method can be called on any + // browser process thread and will not block. + /// + /*--cef(optional_param=client,optional_param=url, + optional_param=request_context)--*/ + static bool CreateBrowser(const CefWindowInfo& windowInfo, + CefRefPtr client, + const CefString& url, + const CefBrowserSettings& settings, + CefRefPtr request_context); + + /// + // Create a new browser window using the window parameters specified by + // |windowInfo|. If |request_context| is empty the global request context + // will be used. This method can only be called on the browser process UI + // thread. + /// + /*--cef(optional_param=client,optional_param=url, + optional_param=request_context)--*/ + static CefRefPtr CreateBrowserSync( + const CefWindowInfo& windowInfo, + CefRefPtr client, + const CefString& url, + const CefBrowserSettings& settings, + CefRefPtr request_context); + + /// + // Returns the hosted browser object. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowser() =0; + + /// + // Call this method before destroying a contained browser window. This method + // performs any internal cleanup that may be needed before the browser window + // is destroyed. See CefLifeSpanHandler::DoClose() documentation for + // additional usage information. + /// + /*--cef()--*/ + virtual void ParentWindowWillClose() =0; + + /// + // Request that the browser close. The JavaScript 'onbeforeunload' event will + // be fired. If |force_close| is false the event handler, if any, will be + // allowed to prompt the user and the user can optionally cancel the close. + // If |force_close| is true the prompt will not be displayed and the close + // will proceed. Results in a call to CefLifeSpanHandler::DoClose() if the + // event handler allows the close or if |force_close| is true. See + // CefLifeSpanHandler::DoClose() documentation for additional usage + // information. + /// + /*--cef()--*/ + virtual void CloseBrowser(bool force_close) =0; + + /// + // Set focus for the browser window. If |enable| is true focus will be set to + // the window. Otherwise, focus will be removed. + /// + /*--cef()--*/ + virtual void SetFocus(bool enable) =0; + + /// + // Retrieve the window handle for this browser. + /// + /*--cef()--*/ + virtual CefWindowHandle GetWindowHandle() =0; + + /// + // Retrieve the window handle of the browser that opened this browser. Will + // return NULL for non-popup windows. This method can be used in combination + // with custom handling of modal windows. + /// + /*--cef()--*/ + virtual CefWindowHandle GetOpenerWindowHandle() =0; + + /// + // Returns the client for this browser. + /// + /*--cef()--*/ + virtual CefRefPtr GetClient() =0; + + /// + // Returns the request context for this browser. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequestContext() =0; + + /// + // Returns the DevTools URL for this browser. If |http_scheme| is true the + // returned URL will use the http scheme instead of the chrome-devtools + // scheme. Remote debugging can be enabled by specifying the + // "remote-debugging-port" command-line flag or by setting the + // CefSettings.remote_debugging_port value. If remote debugging is not enabled + // this method will return an empty string. + /// + /*--cef()--*/ + virtual CefString GetDevToolsURL(bool http_scheme) =0; + + /// + // Get the current zoom level. The default zoom level is 0.0. This method can + // only be called on the UI thread. + /// + /*--cef()--*/ + virtual double GetZoomLevel() =0; + + /// + // Change the zoom level to the specified value. Specify 0.0 to reset the + // zoom level. If called on the UI thread the change will be applied + // immediately. Otherwise, the change will be applied asynchronously on the + // UI thread. + /// + /*--cef()--*/ + virtual void SetZoomLevel(double zoomLevel) =0; + + /// + // Call to run a file chooser dialog. Only a single file chooser dialog may be + // pending at any given time. |mode| represents the type of dialog to display. + // |title| to the title to be used for the dialog and may be empty to show the + // default title ("Open" or "Save" depending on the mode). |default_file_name| + // is the default file name to select in the dialog. |accept_types| is a list + // of valid lower-cased MIME types or file extensions specified in an input + // element and is used to restrict selectable files to such types. |callback| + // will be executed after the dialog is dismissed or immediately if another + // dialog is already pending. The dialog will be initiated asynchronously on + // the UI thread. + /// + /*--cef(optional_param=title,optional_param=default_file_name, + optional_param=accept_types)--*/ + virtual void RunFileDialog(FileDialogMode mode, + const CefString& title, + const CefString& default_file_name, + const std::vector& accept_types, + CefRefPtr callback) =0; + + /// + // Download the file at |url| using CefDownloadHandler. + /// + /*--cef()--*/ + virtual void StartDownload(const CefString& url) =0; + + /// + // Print the current browser contents. + /// + /*--cef()--*/ + virtual void Print() =0; + + /// + // Search for |searchText|. |identifier| can be used to have multiple searches + // running simultaniously. |forward| indicates whether to search forward or + // backward within the page. |matchCase| indicates whether the search should + // be case-sensitive. |findNext| indicates whether this is the first request + // or a follow-up. + /// + /*--cef()--*/ + virtual void Find(int identifier, const CefString& searchText, + bool forward, bool matchCase, bool findNext) =0; + + /// + // Cancel all searches that are currently going on. + /// + /*--cef()--*/ + virtual void StopFinding(bool clearSelection) =0; + + /// + // Set whether mouse cursor change is disabled. + /// + /*--cef()--*/ + virtual void SetMouseCursorChangeDisabled(bool disabled) =0; + + /// + // Returns true if mouse cursor change is disabled. + /// + /*--cef()--*/ + virtual bool IsMouseCursorChangeDisabled() =0; + + /// + // Returns true if window rendering is disabled. + /// + /*--cef()--*/ + virtual bool IsWindowRenderingDisabled() =0; + + /// + // Notify the browser that the widget has been resized. The browser will first + // call CefRenderHandler::GetViewRect to get the new size and then call + // CefRenderHandler::OnPaint asynchronously with the updated regions. This + // method is only used when window rendering is disabled. + /// + /*--cef()--*/ + virtual void WasResized() =0; + + /// + // Notify the browser that it has been hidden or shown. Layouting and + // CefRenderHandler::OnPaint notification will stop when the browser is + // hidden. This method is only used when window rendering is disabled. + /// + /*--cef()--*/ + virtual void WasHidden(bool hidden) =0; + + /// + // Send a notification to the browser that the screen info has changed. The + // browser will then call CefRenderHandler::GetScreenInfo to update the + // screen information with the new values. This simulates moving the webview + // window from one display to another, or changing the properties of the + // current display. This method is only used when window rendering is + // disabled. + /// + /*--cef()--*/ + virtual void NotifyScreenInfoChanged() =0; + + /// + // Invalidate the |dirtyRect| region of the view. The browser will call + // CefRenderHandler::OnPaint asynchronously with the updated regions. This + // method is only used when window rendering is disabled. + /// + /*--cef()--*/ + virtual void Invalidate(const CefRect& dirtyRect, PaintElementType type) =0; + + /// + // Send a key event to the browser. + /// + /*--cef()--*/ + virtual void SendKeyEvent(const CefKeyEvent& event) =0; + + /// + // Send a mouse click event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. + /// + /*--cef()--*/ + virtual void SendMouseClickEvent(const CefMouseEvent& event, + MouseButtonType type, + bool mouseUp, int clickCount) =0; + + /// + // Send a mouse move event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. + /// + /*--cef()--*/ + virtual void SendMouseMoveEvent(const CefMouseEvent& event, + bool mouseLeave) =0; + + /// + // Send a mouse wheel event to the browser. The |x| and |y| coordinates are + // relative to the upper-left corner of the view. The |deltaX| and |deltaY| + // values represent the movement delta in the X and Y directions respectively. + // In order to scroll inside select popups with window rendering disabled + // CefRenderHandler::GetScreenPoint should be implemented properly. + /// + /*--cef()--*/ + virtual void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, int deltaY) =0; + + /// + // Send a focus event to the browser. + /// + /*--cef()--*/ + virtual void SendFocusEvent(bool setFocus) =0; + + /// + // Send a capture lost event to the browser. + /// + /*--cef()--*/ + virtual void SendCaptureLostEvent() =0; + + /// + // Get the NSTextInputContext implementation for enabling IME on Mac when + // window rendering is disabled. + /// + /*--cef(default_retval=NULL)--*/ + virtual CefTextInputContext GetNSTextInputContext() =0; + + /// + // Handles a keyDown event prior to passing it through the NSTextInputClient + // machinery. + /// + /*--cef()--*/ + virtual void HandleKeyEventBeforeTextInputClient(CefEventHandle keyEvent) =0; + + /// + // Performs any additional actions after NSTextInputClient handles the event. + /// + /*--cef()--*/ + virtual void HandleKeyEventAfterTextInputClient(CefEventHandle keyEvent) =0; +}; + +#endif // CEF_INCLUDE_CEF_BROWSER_H_ diff --git a/cefpython/cef3/include/cef_browser_process_handler.h b/cefpython/cef3/include/cef_browser_process_handler.h new file mode 100644 index 00000000..66cc2862 --- /dev/null +++ b/cefpython/cef3/include/cef_browser_process_handler.h @@ -0,0 +1,82 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ +#define CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_command_line.h" +#include "include/cef_values.h" + +/// +// Class used to implement browser process callbacks. The methods of this class +// will be called on the browser process main thread unless otherwise indicated. +/// +/*--cef(source=client)--*/ +class CefBrowserProcessHandler : public virtual CefBase { + public: + /// + // Called on the browser process UI thread immediately after the CEF context + // has been initialized. + /// + /*--cef()--*/ + virtual void OnContextInitialized() {} + + /// + // Called before a child process is launched. Will be called on the browser + // process UI thread when launching a render process and on the browser + // process IO thread when launching a GPU or plugin process. Provides an + // opportunity to modify the child process command line. Do not keep a + // reference to |command_line| outside of this method. + /// + /*--cef()--*/ + virtual void OnBeforeChildProcessLaunch( + CefRefPtr command_line) {} + + /// + // Called on the browser process IO thread after the main thread has been + // created for a new render process. Provides an opportunity to specify extra + // information that will be passed to + // CefRenderProcessHandler::OnRenderThreadCreated() in the render process. Do + // not keep a reference to |extra_info| outside of this method. + /// + /*--cef()--*/ + virtual void OnRenderProcessThreadCreated( + CefRefPtr extra_info) {} +}; + +#endif // CEF_INCLUDE_CEF_BROWSER_PROCESS_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_callback.h b/cefpython/cef3/include/cef_callback.h new file mode 100644 index 00000000..9b4e5321 --- /dev/null +++ b/cefpython/cef3/include/cef_callback.h @@ -0,0 +1,75 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_CALLBACK_H_ +#define CEF_INCLUDE_CEF_CALLBACK_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Generic callback interface used for asynchronous continuation. +/// +/*--cef(source=library)--*/ +class CefCallback : public virtual CefBase { + public: + /// + // Continue processing. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue() =0; + + /// + // Cancel processing. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +/// +// Generic callback interface used for asynchronous completion. +/// +/*--cef(source=client)--*/ +class CefCompletionHandler : public virtual CefBase { + public: + /// + // Method that will be called once the task is complete. + /// + /*--cef()--*/ + virtual void OnComplete() =0; +}; + +#endif // CEF_INCLUDE_CEF_CALLBACK_H_ diff --git a/cefpython/cef3/include/cef_client.h b/cefpython/cef3/include/cef_client.h new file mode 100644 index 00000000..d413e0e6 --- /dev/null +++ b/cefpython/cef3/include/cef_client.h @@ -0,0 +1,185 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_CLIENT_H_ +#define CEF_INCLUDE_CEF_CLIENT_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_context_menu_handler.h" +#include "include/cef_dialog_handler.h" +#include "include/cef_display_handler.h" +#include "include/cef_download_handler.h" +#include "include/cef_drag_handler.h" +#include "include/cef_focus_handler.h" +#include "include/cef_geolocation_handler.h" +#include "include/cef_jsdialog_handler.h" +#include "include/cef_keyboard_handler.h" +#include "include/cef_life_span_handler.h" +#include "include/cef_load_handler.h" +#include "include/cef_process_message.h" +#include "include/cef_render_handler.h" +#include "include/cef_request_handler.h" + +/// +// Implement this interface to provide handler implementations. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefClient : public virtual CefBase { + public: + /// + // Return the handler for context menus. If no handler is provided the default + // implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetContextMenuHandler() { + return NULL; + } + + /// + // Return the handler for dialogs. If no handler is provided the default + // implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetDialogHandler() { + return NULL; + } + + /// + // Return the handler for browser display state events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDisplayHandler() { + return NULL; + } + + /// + // Return the handler for download events. If no handler is returned downloads + // will not be allowed. + /// + /*--cef()--*/ + virtual CefRefPtr GetDownloadHandler() { + return NULL; + } + + /// + // Return the handler for drag events. + /// + /*--cef()--*/ + virtual CefRefPtr GetDragHandler() { + return NULL; + } + + /// + // Return the handler for focus events. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusHandler() { + return NULL; + } + + /// + // Return the handler for geolocation permissions requests. If no handler is + // provided geolocation access will be denied by default. + /// + /*--cef()--*/ + virtual CefRefPtr GetGeolocationHandler() { + return NULL; + } + + /// + // Return the handler for JavaScript dialogs. If no handler is provided the + // default implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetJSDialogHandler() { + return NULL; + } + + /// + // Return the handler for keyboard events. + /// + /*--cef()--*/ + virtual CefRefPtr GetKeyboardHandler() { + return NULL; + } + + /// + // Return the handler for browser life span events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLifeSpanHandler() { + return NULL; + } + + /// + // Return the handler for browser load status events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLoadHandler() { + return NULL; + } + + /// + // Return the handler for off-screen rendering events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRenderHandler() { + return NULL; + } + + /// + // Return the handler for browser request events. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequestHandler() { + return NULL; + } + + /// + // Called when a new message is received from a different process. Return true + // if the message was handled or false otherwise. Do not keep a reference to + // or attempt to access the message outside of this callback. + /// + /*--cef()--*/ + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + return false; + } +}; + +#endif // CEF_INCLUDE_CEF_CLIENT_H_ diff --git a/cefpython/cef3/include/cef_command_line.h b/cefpython/cef3/include/cef_command_line.h new file mode 100644 index 00000000..96241cf4 --- /dev/null +++ b/cefpython/cef3/include/cef_command_line.h @@ -0,0 +1,208 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_COMMAND_LINE_H_ +#define CEF_INCLUDE_CEF_COMMAND_LINE_H_ +#pragma once + +#include "include/cef_base.h" +#include +#include + +/// +// Class used to create and/or parse command line arguments. Arguments with +// '--', '-' and, on Windows, '/' prefixes are considered switches. Switches +// will always precede any arguments without switch prefixes. Switches can +// optionally have a value specified using the '=' delimiter (e.g. +// "-switch=value"). An argument of "--" will terminate switch parsing with all +// subsequent tokens, regardless of prefix, being interpreted as non-switch +// arguments. Switch names are considered case-insensitive. This class can be +// used before CefInitialize() is called. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefCommandLine : public virtual CefBase { + public: + typedef std::vector ArgumentList; + typedef std::map SwitchMap; + + /// + // Create a new CefCommandLine instance. + /// + /*--cef(api_hash_check)--*/ + static CefRefPtr CreateCommandLine(); + + /// + // Returns the singleton global CefCommandLine object. The returned object + // will be read-only. + /// + /*--cef(api_hash_check)--*/ + static CefRefPtr GetGlobalCommandLine(); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // function returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if the values of this object are read-only. Some APIs may + // expose read-only objects. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Returns a writable copy of this object. + /// + /*--cef()--*/ + virtual CefRefPtr Copy() =0; + + /// + // Initialize the command line with the specified |argc| and |argv| values. + // The first argument must be the name of the program. This method is only + // supported on non-Windows platforms. + /// + /*--cef()--*/ + virtual void InitFromArgv(int argc, const char* const* argv) =0; + + /// + // Initialize the command line with the string returned by calling + // GetCommandLineW(). This method is only supported on Windows. + /// + /*--cef()--*/ + virtual void InitFromString(const CefString& command_line) =0; + + /// + // Reset the command-line switches and arguments but leave the program + // component unchanged. + /// + /*--cef()--*/ + virtual void Reset() =0; + + /// + // Retrieve the original command line string as a vector of strings. + // The argv array: { program, [(--|-|/)switch[=value]]*, [--], [argument]* } + /// + /*--cef()--*/ + virtual void GetArgv(std::vector& argv) =0; + + /// + // Constructs and returns the represented command line string. Use this method + // cautiously because quoting behavior is unclear. + /// + /*--cef()--*/ + virtual CefString GetCommandLineString() =0; + + /// + // Get the program part of the command line string (the first item). + /// + /*--cef()--*/ + virtual CefString GetProgram() =0; + + /// + // Set the program part of the command line string (the first item). + /// + /*--cef()--*/ + virtual void SetProgram(const CefString& program) =0; + + /// + // Returns true if the command line has switches. + /// + /*--cef()--*/ + virtual bool HasSwitches() =0; + + /// + // Returns true if the command line contains the given switch. + /// + /*--cef()--*/ + virtual bool HasSwitch(const CefString& name) =0; + + /// + // Returns the value associated with the given switch. If the switch has no + // value or isn't present this method returns the empty string. + /// + /*--cef()--*/ + virtual CefString GetSwitchValue(const CefString& name) =0; + + /// + // Returns the map of switch names and values. If a switch has no value an + // empty string is returned. + /// + /*--cef()--*/ + virtual void GetSwitches(SwitchMap& switches) =0; + + /// + // Add a switch to the end of the command line. If the switch has no value + // pass an empty value string. + /// + /*--cef()--*/ + virtual void AppendSwitch(const CefString& name) =0; + + /// + // Add a switch with the specified value to the end of the command line. + /// + /*--cef()--*/ + virtual void AppendSwitchWithValue(const CefString& name, + const CefString& value) =0; + + /// + // True if there are remaining command line arguments. + /// + /*--cef()--*/ + virtual bool HasArguments() =0; + + /// + // Get the remaining command line arguments. + /// + /*--cef()--*/ + virtual void GetArguments(ArgumentList& arguments) =0; + + /// + // Add an argument to the end of the command line. + /// + /*--cef()--*/ + virtual void AppendArgument(const CefString& argument) =0; + + /// + // Insert a command before the current command. + // Common for debuggers, like "valgrind" or "gdb --args". + /// + /*--cef()--*/ + virtual void PrependWrapper(const CefString& wrapper) =0; +}; + +#endif // CEF_INCLUDE_CEF_COMMAND_LINE_H_ diff --git a/cefpython/cef3/include/cef_context_menu_handler.h b/cefpython/cef3/include/cef_context_menu_handler.h new file mode 100644 index 00000000..239f6a43 --- /dev/null +++ b/cefpython/cef3/include/cef_context_menu_handler.h @@ -0,0 +1,217 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_CONTEXT_MENU_HANDLER_H_ +#define CEF_INCLUDE_CEF_CONTEXT_MENU_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include "include/cef_menu_model.h" + +class CefContextMenuParams; + +/// +// Implement this interface to handle context menu events. The methods of this +// class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefContextMenuHandler : public virtual CefBase { + public: + typedef cef_event_flags_t EventFlags; + + /// + // Called before a context menu is displayed. |params| provides information + // about the context menu state. |model| initially contains the default + // context menu. The |model| can be cleared to show no context menu or + // modified to show a custom menu. Do not keep references to |params| or + // |model| outside of this callback. + /// + /*--cef()--*/ + virtual void OnBeforeContextMenu(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + CefRefPtr model) {} + + /// + // Called to execute a command selected from the context menu. Return true if + // the command was handled or false for the default implementation. See + // cef_menu_id_t for the command ids that have default implementations. All + // user-defined command ids should be between MENU_ID_USER_FIRST and + // MENU_ID_USER_LAST. |params| will have the same values as what was passed to + // OnBeforeContextMenu(). Do not keep a reference to |params| outside of this + // callback. + /// + /*--cef()--*/ + virtual bool OnContextMenuCommand(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr params, + int command_id, + EventFlags event_flags) { return false; } + + /// + // Called when the context menu is dismissed irregardless of whether the menu + // was empty or a command was selected. + /// + /*--cef()--*/ + virtual void OnContextMenuDismissed(CefRefPtr browser, + CefRefPtr frame) {} +}; + + +/// +// Provides information about the context menu state. The ethods of this class +// can only be accessed on browser process the UI thread. +/// +/*--cef(source=library)--*/ +class CefContextMenuParams : public virtual CefBase { + public: + typedef cef_context_menu_type_flags_t TypeFlags; + typedef cef_context_menu_media_type_t MediaType; + typedef cef_context_menu_media_state_flags_t MediaStateFlags; + typedef cef_context_menu_edit_state_flags_t EditStateFlags; + + /// + // Returns the X coordinate of the mouse where the context menu was invoked. + // Coords are relative to the associated RenderView's origin. + /// + /*--cef()--*/ + virtual int GetXCoord() =0; + + /// + // Returns the Y coordinate of the mouse where the context menu was invoked. + // Coords are relative to the associated RenderView's origin. + /// + /*--cef()--*/ + virtual int GetYCoord() =0; + + /// + // Returns flags representing the type of node that the context menu was + // invoked on. + /// + /*--cef(default_retval=CM_TYPEFLAG_NONE)--*/ + virtual TypeFlags GetTypeFlags() =0; + + /// + // Returns the URL of the link, if any, that encloses the node that the + // context menu was invoked on. + /// + /*--cef()--*/ + virtual CefString GetLinkUrl() =0; + + /// + // Returns the link URL, if any, to be used ONLY for "copy link address". We + // don't validate this field in the frontend process. + /// + /*--cef()--*/ + virtual CefString GetUnfilteredLinkUrl() =0; + + /// + // Returns the source URL, if any, for the element that the context menu was + // invoked on. Example of elements with source URLs are img, audio, and video. + /// + /*--cef()--*/ + virtual CefString GetSourceUrl() =0; + + /// + // Returns true if the context menu was invoked on an image which has + // non-empty contents. + /// + /*--cef()--*/ + virtual bool HasImageContents() =0; + + /// + // Returns the URL of the top level page that the context menu was invoked on. + /// + /*--cef()--*/ + virtual CefString GetPageUrl() =0; + + /// + // Returns the URL of the subframe that the context menu was invoked on. + /// + /*--cef()--*/ + virtual CefString GetFrameUrl() =0; + + /// + // Returns the character encoding of the subframe that the context menu was + // invoked on. + /// + /*--cef()--*/ + virtual CefString GetFrameCharset() =0; + + /// + // Returns the type of context node that the context menu was invoked on. + /// + /*--cef(default_retval=CM_MEDIATYPE_NONE)--*/ + virtual MediaType GetMediaType() =0; + + /// + // Returns flags representing the actions supported by the media element, if + // any, that the context menu was invoked on. + /// + /*--cef(default_retval=CM_MEDIAFLAG_NONE)--*/ + virtual MediaStateFlags GetMediaStateFlags() =0; + + /// + // Returns the text of the selection, if any, that the context menu was + // invoked on. + /// + /*--cef()--*/ + virtual CefString GetSelectionText() =0; + + /// + // Returns true if the context menu was invoked on an editable node. + /// + /*--cef()--*/ + virtual bool IsEditable() =0; + + /// + // Returns true if the context menu was invoked on an editable node where + // speech-input is enabled. + /// + /*--cef()--*/ + virtual bool IsSpeechInputEnabled() =0; + + /// + // Returns flags representing the actions supported by the editable node, if + // any, that the context menu was invoked on. + /// + /*--cef(default_retval=CM_EDITFLAG_NONE)--*/ + virtual EditStateFlags GetEditStateFlags() =0; +}; + +#endif // CEF_INCLUDE_CEF_CONTEXT_MENU_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_cookie.h b/cefpython/cef3/include/cef_cookie.h new file mode 100644 index 00000000..807279b7 --- /dev/null +++ b/cefpython/cef3/include/cef_cookie.h @@ -0,0 +1,166 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_COOKIE_H_ +#define CEF_INCLUDE_CEF_COOKIE_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_callback.h" +#include + +class CefCookieVisitor; + + +/// +// Class used for managing cookies. The methods of this class may be called on +// any thread unless otherwise indicated. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefCookieManager : public virtual CefBase { + public: + /// + // Returns the global cookie manager. By default data will be stored at + // CefSettings.cache_path if specified or in memory otherwise. + /// + /*--cef()--*/ + static CefRefPtr GetGlobalManager(); + + /// + // Creates a new cookie manager. If |path| is empty data will be stored in + // memory only. Otherwise, data will be stored at the specified |path|. To + // persist session cookies (cookies without an expiry date or validity + // interval) set |persist_session_cookies| to true. Session cookies are + // generally intended to be transient and most Web browsers do not persist + // them. Returns NULL if creation fails. + /// + /*--cef(optional_param=path)--*/ + static CefRefPtr CreateManager( + const CefString& path, + bool persist_session_cookies); + + /// + // Set the schemes supported by this manager. By default only "http" and + // "https" schemes are supported. Must be called before any cookies are + // accessed. + /// + /*--cef()--*/ + virtual void SetSupportedSchemes(const std::vector& schemes) =0; + + /// + // Visit all cookies. The returned cookies are ordered by longest path, then + // by earliest creation date. Returns false if cookies cannot be accessed. + /// + /*--cef()--*/ + virtual bool VisitAllCookies(CefRefPtr visitor) =0; + + /// + // Visit a subset of cookies. The results are filtered by the given url + // scheme, host, domain and path. If |includeHttpOnly| is true HTTP-only + // cookies will also be included in the results. The returned cookies are + // ordered by longest path, then by earliest creation date. Returns false if + // cookies cannot be accessed. + /// + /*--cef()--*/ + virtual bool VisitUrlCookies(const CefString& url, bool includeHttpOnly, + CefRefPtr visitor) =0; + + /// + // Sets a cookie given a valid URL and explicit user-provided cookie + // attributes. This function expects each attribute to be well-formed. It will + // check for disallowed characters (e.g. the ';' character is disallowed + // within the cookie value attribute) and will return false without setting + // the cookie if such characters are found. This method must be called on the + // IO thread. + /// + /*--cef()--*/ + virtual bool SetCookie(const CefString& url, const CefCookie& cookie) =0; + + /// + // Delete all cookies that match the specified parameters. If both |url| and + // values |cookie_name| are specified all host and domain cookies matching + // both will be deleted. If only |url| is specified all host cookies (but not + // domain cookies) irrespective of path will be deleted. If |url| is empty all + // cookies for all hosts and domains will be deleted. Returns false if a non- + // empty invalid URL is specified or if cookies cannot be accessed. This + // method must be called on the IO thread. + /// + /*--cef(optional_param=url,optional_param=cookie_name)--*/ + virtual bool DeleteCookies(const CefString& url, + const CefString& cookie_name) =0; + + /// + // Sets the directory path that will be used for storing cookie data. If + // |path| is empty data will be stored in memory only. Otherwise, data will be + // stored at the specified |path|. To persist session cookies (cookies without + // an expiry date or validity interval) set |persist_session_cookies| to true. + // Session cookies are generally intended to be transient and most Web browsers + // do not persist them. Returns false if cookies cannot be accessed. + /// + /*--cef(optional_param=path)--*/ + virtual bool SetStoragePath(const CefString& path, + bool persist_session_cookies) =0; + + /// + // Flush the backing store (if any) to disk and execute the specified + // |handler| on the IO thread when done. Returns false if cookies cannot be + // accessed. + /// + /*--cef(optional_param=handler)--*/ + virtual bool FlushStore(CefRefPtr handler) =0; +}; + + +/// +// Interface to implement for visiting cookie values. The methods of this class +// will always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefCookieVisitor : public virtual CefBase { + public: + /// + // Method that will be called once for each cookie. |count| is the 0-based + // index for the current cookie. |total| is the total number of cookies. + // Set |deleteCookie| to true to delete the cookie currently being visited. + // Return false to stop visiting cookies. This method may never be called if + // no cookies are found. + /// + /*--cef()--*/ + virtual bool Visit(const CefCookie& cookie, int count, int total, + bool& deleteCookie) =0; +}; + +#endif // CEF_INCLUDE_CEF_COOKIE_H_ diff --git a/cefpython/cef3/include/cef_dialog_handler.h b/cefpython/cef3/include/cef_dialog_handler.h new file mode 100644 index 00000000..83e1048a --- /dev/null +++ b/cefpython/cef3/include/cef_dialog_handler.h @@ -0,0 +1,98 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DIALOG_HANDLER_H_ +#define CEF_INCLUDE_CEF_DIALOG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Callback interface for asynchronous continuation of file dialog requests. +/// +/*--cef(source=library)--*/ +class CefFileDialogCallback : public virtual CefBase { + public: + /// + // Continue the file selection with the specified |file_paths|. This may be + // a single value or a list of values depending on the dialog mode. An empty + // value is treated the same as calling Cancel(). + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(const std::vector& file_paths) =0; + + /// + // Cancel the file selection. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + + +/// +// Implement this interface to handle dialog events. The methods of this class +// will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefDialogHandler : public virtual CefBase { + public: + typedef cef_file_dialog_mode_t FileDialogMode; + + /// + // Called to run a file chooser dialog. |mode| represents the type of dialog + // to display. |title| to the title to be used for the dialog and may be empty + // to show the default title ("Open" or "Save" depending on the mode). + // |default_file_name| is the default file name to select in the dialog. + // |accept_types| is a list of valid lower-cased MIME types or file extensions + // specified in an input element and is used to restrict selectable files to + // such types. To display a custom dialog return true and execute |callback| + // either inline or at a later time. To display the default dialog return + // false. + /// + /*--cef(optional_param=title,optional_param=default_file_name, + optional_param=accept_types)--*/ + virtual bool OnFileDialog(CefRefPtr browser, + FileDialogMode mode, + const CefString& title, + const CefString& default_file_name, + const std::vector& accept_types, + CefRefPtr callback) { + return false; + } +}; + +#endif // CEF_INCLUDE_CEF_DIALOG_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_display_handler.h b/cefpython/cef3/include/cef_display_handler.h new file mode 100644 index 00000000..2eb69eda --- /dev/null +++ b/cefpython/cef3/include/cef_display_handler.h @@ -0,0 +1,99 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ +#define CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to browser display state. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDisplayHandler : public virtual CefBase { + public: + /// + // Called when a frame's address has changed. + /// + /*--cef()--*/ + virtual void OnAddressChange(CefRefPtr browser, + CefRefPtr frame, + const CefString& url) {} + + /// + // Called when the page title changes. + /// + /*--cef(optional_param=title)--*/ + virtual void OnTitleChange(CefRefPtr browser, + const CefString& title) {} + + /// + // Called when the browser is about to display a tooltip. |text| contains the + // text that will be displayed in the tooltip. To handle the display of the + // tooltip yourself return true. Otherwise, you can optionally modify |text| + // and then return false to allow the browser to display the tooltip. + // When window rendering is disabled the application is responsible for + // drawing tooltips and the return value is ignored. + /// + /*--cef(optional_param=text)--*/ + virtual bool OnTooltip(CefRefPtr browser, + CefString& text) { return false; } + + /// + // Called when the browser receives a status message. |text| contains the text + // that will be displayed in the status message and |type| indicates the + // status message type. + /// + /*--cef(optional_param=value)--*/ + virtual void OnStatusMessage(CefRefPtr browser, + const CefString& value) {} + + /// + // Called to display a console message. Return true to stop the message from + // being output to the console. + /// + /*--cef(optional_param=message,optional_param=source)--*/ + virtual bool OnConsoleMessage(CefRefPtr browser, + const CefString& message, + const CefString& source, + int line) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_dom.h b/cefpython/cef3/include/cef_dom.h new file mode 100644 index 00000000..f155e2f3 --- /dev/null +++ b/cefpython/cef3/include/cef_dom.h @@ -0,0 +1,435 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DOM_H_ +#define CEF_INCLUDE_CEF_DOM_H_ +#pragma once + +#include "include/cef_base.h" +#include + +class CefDOMDocument; +class CefDOMEventListener; +class CefDOMNode; + +/// +// Interface to implement for visiting the DOM. The methods of this class will +// be called on the render process main thread. +/// +/*--cef(source=client)--*/ +class CefDOMVisitor : public virtual CefBase { + public: + /// + // Method executed for visiting the DOM. The document object passed to this + // method represents a snapshot of the DOM at the time this method is + // executed. DOM objects are only valid for the scope of this method. Do not + // keep references to or attempt to access any DOM objects outside the scope + // of this method. + /// + /*--cef()--*/ + virtual void Visit(CefRefPtr document) =0; +}; + + +/// +// Class used to represent a DOM document. The methods of this class should only +// be called on the render process main thread thread. +/// +/*--cef(source=library)--*/ +class CefDOMDocument : public virtual CefBase { + public: + typedef cef_dom_document_type_t Type; + + /// + // Returns the document type. + /// + /*--cef(default_retval=DOM_DOCUMENT_TYPE_UNKNOWN)--*/ + virtual Type GetType() =0; + + /// + // Returns the root document node. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the BODY node of an HTML document. + /// + /*--cef()--*/ + virtual CefRefPtr GetBody() =0; + + /// + // Returns the HEAD node of an HTML document. + /// + /*--cef()--*/ + virtual CefRefPtr GetHead() =0; + + /// + // Returns the title of an HTML document. + /// + /*--cef()--*/ + virtual CefString GetTitle() =0; + + /// + // Returns the document element with the specified ID value. + /// + /*--cef()--*/ + virtual CefRefPtr GetElementById(const CefString& id) =0; + + /// + // Returns the node that currently has keyboard focus. + /// + /*--cef()--*/ + virtual CefRefPtr GetFocusedNode() =0; + + /// + // Returns true if a portion of the document is selected. + /// + /*--cef()--*/ + virtual bool HasSelection() =0; + + /// + // Returns the selection start node. + /// + /*--cef()--*/ + virtual CefRefPtr GetSelectionStartNode() =0; + + /// + // Returns the selection offset within the start node. + /// + /*--cef()--*/ + virtual int GetSelectionStartOffset() =0; + + /// + // Returns the selection end node. + /// + /*--cef()--*/ + virtual CefRefPtr GetSelectionEndNode() =0; + + /// + // Returns the selection offset within the end node. + /// + /*--cef()--*/ + virtual int GetSelectionEndOffset() =0; + + /// + // Returns the contents of this selection as markup. + /// + /*--cef()--*/ + virtual CefString GetSelectionAsMarkup() =0; + + /// + // Returns the contents of this selection as text. + /// + /*--cef()--*/ + virtual CefString GetSelectionAsText() =0; + + /// + // Returns the base URL for the document. + /// + /*--cef()--*/ + virtual CefString GetBaseURL() =0; + + /// + // Returns a complete URL based on the document base URL and the specified + // partial URL. + /// + /*--cef()--*/ + virtual CefString GetCompleteURL(const CefString& partialURL) =0; +}; + + +/// +// Class used to represent a DOM node. The methods of this class should only be +// called on the render process main thread. +/// +/*--cef(source=library)--*/ +class CefDOMNode : public virtual CefBase { + public: + typedef std::map AttributeMap; + typedef cef_dom_node_type_t Type; + + /// + // Returns the type for this node. + /// + /*--cef(default_retval=DOM_NODE_TYPE_UNSUPPORTED)--*/ + virtual Type GetType() =0; + + /// + // Returns true if this is a text node. + /// + /*--cef()--*/ + virtual bool IsText() =0; + + /// + // Returns true if this is an element node. + /// + /*--cef()--*/ + virtual bool IsElement() =0; + + /// + // Returns true if this is an editable node. + /// + /*--cef()--*/ + virtual bool IsEditable() =0; + + /// + // Returns true if this is a form control element node. + /// + /*--cef()--*/ + virtual bool IsFormControlElement() =0; + + /// + // Returns the type of this form control element node. + /// + /*--cef()--*/ + virtual CefString GetFormControlElementType() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Returns the name of this node. + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the value of this node. + /// + /*--cef()--*/ + virtual CefString GetValue() =0; + + /// + // Set the value of this node. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetValue(const CefString& value) =0; + + /// + // Returns the contents of this node as markup. + /// + /*--cef()--*/ + virtual CefString GetAsMarkup() =0; + + /// + // Returns the document associated with this node. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the parent node. + /// + /*--cef()--*/ + virtual CefRefPtr GetParent() =0; + + /// + // Returns the previous sibling node. + /// + /*--cef()--*/ + virtual CefRefPtr GetPreviousSibling() =0; + + /// + // Returns the next sibling node. + /// + /*--cef()--*/ + virtual CefRefPtr GetNextSibling() =0; + + /// + // Returns true if this node has child nodes. + /// + /*--cef()--*/ + virtual bool HasChildren() =0; + + /// + // Return the first child node. + /// + /*--cef()--*/ + virtual CefRefPtr GetFirstChild() =0; + + /// + // Returns the last child node. + /// + /*--cef()--*/ + virtual CefRefPtr GetLastChild() =0; + + /// + // Add an event listener to this node for the specified event type. If + // |useCapture| is true then this listener will be considered a capturing + // listener. Capturing listeners will recieve all events of the specified + // type before the events are dispatched to any other event targets beneath + // the current node in the tree. Events which are bubbling upwards through + // the tree will not trigger a capturing listener. Separate calls to this + // method can be used to register the same listener with and without capture. + // See WebCore/dom/EventNames.h for the list of supported event types. + /// + /*--cef()--*/ + virtual void AddEventListener(const CefString& eventType, + CefRefPtr listener, + bool useCapture) =0; + + + // The following methods are valid only for element nodes. + + /// + // Returns the tag name of this element. + /// + /*--cef()--*/ + virtual CefString GetElementTagName() =0; + + /// + // Returns true if this element has attributes. + /// + /*--cef()--*/ + virtual bool HasElementAttributes() =0; + + /// + // Returns true if this element has an attribute named |attrName|. + /// + /*--cef()--*/ + virtual bool HasElementAttribute(const CefString& attrName) =0; + + /// + // Returns the element attribute named |attrName|. + /// + /*--cef()--*/ + virtual CefString GetElementAttribute(const CefString& attrName) =0; + + /// + // Returns a map of all element attributes. + /// + /*--cef()--*/ + virtual void GetElementAttributes(AttributeMap& attrMap) =0; + + /// + // Set the value for the element attribute named |attrName|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool SetElementAttribute(const CefString& attrName, + const CefString& value) =0; + + /// + // Returns the inner text of the element. + /// + /*--cef()--*/ + virtual CefString GetElementInnerText() =0; +}; + + +/// +// Class used to represent a DOM event. The methods of this class should only +// be called on the render process main thread. +/// +/*--cef(source=library)--*/ +class CefDOMEvent : public virtual CefBase { + public: + typedef cef_dom_event_category_t Category; + typedef cef_dom_event_phase_t Phase; + + /// + // Returns the event type. + /// + /*--cef()--*/ + virtual CefString GetType() =0; + + /// + // Returns the event category. + /// + /*--cef(default_retval=DOM_EVENT_CATEGORY_UNKNOWN)--*/ + virtual Category GetCategory() =0; + + /// + // Returns the event processing phase. + /// + /*--cef(default_retval=DOM_EVENT_PHASE_UNKNOWN)--*/ + virtual Phase GetPhase() =0; + + /// + // Returns true if the event can bubble up the tree. + /// + /*--cef()--*/ + virtual bool CanBubble() =0; + + /// + // Returns true if the event can be canceled. + /// + /*--cef()--*/ + virtual bool CanCancel() =0; + + /// + // Returns the document associated with this event. + /// + /*--cef()--*/ + virtual CefRefPtr GetDocument() =0; + + /// + // Returns the target of the event. + /// + /*--cef()--*/ + virtual CefRefPtr GetTarget() =0; + + /// + // Returns the current target of the event. + /// + /*--cef()--*/ + virtual CefRefPtr GetCurrentTarget() =0; +}; + + +/// +// Interface to implement for handling DOM events. The methods of this class +// will be called on the render process main thread. +/// +/*--cef(source=client)--*/ +class CefDOMEventListener : public virtual CefBase { + public: + /// + // Called when an event is received. The event object passed to this method + // contains a snapshot of the DOM at the time this method is executed. DOM + // objects are only valid for the scope of this method. Do not keep references + // to or attempt to access any DOM objects outside the scope of this method. + /// + /*--cef()--*/ + virtual void HandleEvent(CefRefPtr event) =0; +}; + +#endif // CEF_INCLUDE_CEF_DOM_H_ diff --git a/cefpython/cef3/include/cef_download_handler.h b/cefpython/cef3/include/cef_download_handler.h new file mode 100644 index 00000000..f7c26b3c --- /dev/null +++ b/cefpython/cef3/include/cef_download_handler.h @@ -0,0 +1,112 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ +#define CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_download_item.h" + + +/// +// Callback interface used to asynchronously continue a download. +/// +/*--cef(source=library)--*/ +class CefBeforeDownloadCallback : public virtual CefBase { + public: + /// + // Call to continue the download. Set |download_path| to the full file path + // for the download including the file name or leave blank to use the + // suggested name and the default temp directory. Set |show_dialog| to true + // if you do wish to show the default "Save As" dialog. + /// + /*--cef(capi_name=cont,optional_param=download_path)--*/ + virtual void Continue(const CefString& download_path, bool show_dialog) =0; +}; + + +/// +// Callback interface used to asynchronously cancel a download. +/// +/*--cef(source=library)--*/ +class CefDownloadItemCallback : public virtual CefBase { + public: + /// + // Call to cancel the download. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + + +/// +// Class used to handle file downloads. The methods of this class will called +// on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefDownloadHandler : public virtual CefBase { + public: + /// + // Called before a download begins. |suggested_name| is the suggested name for + // the download file. By default the download will be canceled. Execute + // |callback| either asynchronously or in this method to continue the download + // if desired. Do not keep a reference to |download_item| outside of this + // method. + /// + /*--cef()--*/ + virtual void OnBeforeDownload( + CefRefPtr browser, + CefRefPtr download_item, + const CefString& suggested_name, + CefRefPtr callback) =0; + + /// + // Called when a download's status or progress information has been updated. + // This may be called multiple times before and after OnBeforeDownload(). + // Execute |callback| either asynchronously or in this method to cancel the + // download if desired. Do not keep a reference to |download_item| outside of + // this method. + /// + /*--cef()--*/ + virtual void OnDownloadUpdated( + CefRefPtr browser, + CefRefPtr download_item, + CefRefPtr callback) {} +}; + +#endif // CEF_INCLUDE_CEF_DOWNLOAD_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_download_item.h b/cefpython/cef3/include/cef_download_item.h new file mode 100644 index 00000000..6f76ff5e --- /dev/null +++ b/cefpython/cef3/include/cef_download_item.h @@ -0,0 +1,148 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DOWNLOAD_ITEM_H_ +#define CEF_INCLUDE_CEF_DOWNLOAD_ITEM_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Class used to represent a download item. +/// +/*--cef(source=library)--*/ +class CefDownloadItem : public virtual CefBase { + public: + /// + // Returns true if this object is valid. Do not call any other methods if this + // function returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if the download is in progress. + /// + /*--cef()--*/ + virtual bool IsInProgress() =0; + + /// + // Returns true if the download is complete. + /// + /*--cef()--*/ + virtual bool IsComplete() =0; + + /// + // Returns true if the download has been canceled or interrupted. + /// + /*--cef()--*/ + virtual bool IsCanceled() =0; + + /// + // Returns a simple speed estimate in bytes/s. + /// + /*--cef()--*/ + virtual int64 GetCurrentSpeed() =0; + + /// + // Returns the rough percent complete or -1 if the receive total size is + // unknown. + /// + /*--cef()--*/ + virtual int GetPercentComplete() =0; + + /// + // Returns the total number of bytes. + /// + /*--cef()--*/ + virtual int64 GetTotalBytes() =0; + + /// + // Returns the number of received bytes. + /// + /*--cef()--*/ + virtual int64 GetReceivedBytes() =0; + + /// + // Returns the time that the download started. + /// + /*--cef()--*/ + virtual CefTime GetStartTime() =0; + + /// + // Returns the time that the download ended. + /// + /*--cef()--*/ + virtual CefTime GetEndTime() =0; + + /// + // Returns the full path to the downloaded or downloading file. + /// + /*--cef()--*/ + virtual CefString GetFullPath() =0; + + /// + // Returns the unique identifier for this download. + /// + /*--cef()--*/ + virtual uint32 GetId() =0; + + /// + // Returns the URL. + /// + /*--cef()--*/ + virtual CefString GetURL() =0; + + /// + // Returns the suggested file name. + /// + /*--cef()--*/ + virtual CefString GetSuggestedFileName() =0; + + /// + // Returns the content disposition. + /// + /*--cef()--*/ + virtual CefString GetContentDisposition() =0; + + /// + // Returns the mime type. + /// + /*--cef()--*/ + virtual CefString GetMimeType() =0; +}; + +#endif // CEF_INCLUDE_CEF_DOWNLOAD_ITEM_H_ diff --git a/cefpython/cef3/include/cef_drag_data.h b/cefpython/cef3/include/cef_drag_data.h new file mode 100644 index 00000000..58bcc3ed --- /dev/null +++ b/cefpython/cef3/include/cef_drag_data.h @@ -0,0 +1,120 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_DATA_H_ +#define CEF_INCLUDE_CEF_DRAG_DATA_H_ +#pragma once + +#include "include/cef_base.h" +#include + +/// +// Class used to represent drag data. The methods of this class may be called +// on any thread. +/// +/*--cef(source=library)--*/ +class CefDragData : public virtual CefBase { + public: + /// + // Returns true if the drag data is a link. + /// + /*--cef()--*/ + virtual bool IsLink() =0; + + /// + // Returns true if the drag data is a text or html fragment. + /// + /*--cef()--*/ + virtual bool IsFragment() =0; + + /// + // Returns true if the drag data is a file. + /// + /*--cef()--*/ + virtual bool IsFile() =0; + + /// + // Return the link URL that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkURL() =0; + + /// + // Return the title associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkTitle() =0; + + /// + // Return the metadata, if any, associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkMetadata() =0; + + /// + // Return the plain text fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentText() =0; + + /// + // Return the text/html fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentHtml() =0; + + /// + // Return the base URL that the fragment came from. This value is used for + // resolving relative URLs and may be empty. + /// + /*--cef()--*/ + virtual CefString GetFragmentBaseURL() =0; + + /// + // Return the name of the file being dragged out of the browser window. + /// + /*--cef()--*/ + virtual CefString GetFileName() =0; + + /// + // Retrieve the list of file names that are being dragged into the browser + // window. + /// + /*--cef()--*/ + virtual bool GetFileNames(std::vector& names) =0; +}; + +#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_ diff --git a/cefpython/cef3/include/cef_drag_handler.h b/cefpython/cef3/include/cef_drag_handler.h new file mode 100644 index 00000000..7cfc40ba --- /dev/null +++ b/cefpython/cef3/include/cef_drag_handler.h @@ -0,0 +1,66 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#define CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_drag_data.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to dragging. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDragHandler : public virtual CefBase { + public: + typedef cef_drag_operations_mask_t DragOperationsMask; + + /// + // Called when an external drag event enters the browser window. |dragData| + // contains the drag event data and |mask| represents the type of drag + // operation. Return false for default drag handling behavior or true to + // cancel the drag event. + /// + /*--cef()--*/ + virtual bool OnDragEnter(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_DRAG_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_focus_handler.h b/cefpython/cef3/include/cef_focus_handler.h new file mode 100644 index 00000000..1d91c42a --- /dev/null +++ b/cefpython/cef3/include/cef_focus_handler.h @@ -0,0 +1,81 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ +#define CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_dom.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to focus. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefFocusHandler : public virtual CefBase { + public: + typedef cef_focus_source_t FocusSource; + + /// + // Called when the browser component is about to loose focus. For instance, if + // focus was on the last HTML element and the user pressed the TAB key. |next| + // will be true if the browser is giving focus to the next component and false + // if the browser is giving focus to the previous component. + /// + /*--cef()--*/ + virtual void OnTakeFocus(CefRefPtr browser, + bool next) {} + + /// + // Called when the browser component is requesting focus. |source| indicates + // where the focus request is originating from. Return false to allow the + // focus to be set or true to cancel setting the focus. + /// + /*--cef()--*/ + virtual bool OnSetFocus(CefRefPtr browser, + FocusSource source) { return false; } + + /// + // Called when the browser component has received focus. + /// + /*--cef()--*/ + virtual void OnGotFocus(CefRefPtr browser) {} +}; + +#endif // CEF_INCLUDE_CEF_FOCUS_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_frame.h b/cefpython/cef3/include/cef_frame.h new file mode 100644 index 00000000..adba66f1 --- /dev/null +++ b/cefpython/cef3/include/cef_frame.h @@ -0,0 +1,224 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_FRAME_H_ +#define CEF_INCLUDE_CEF_FRAME_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_dom.h" +#include "include/cef_request.h" +#include "include/cef_stream.h" +#include "include/cef_string_visitor.h" + +class CefBrowser; +class CefV8Context; + +/// +// Class used to represent a frame in the browser window. When used in the +// browser process the methods of this class may be called on any thread unless +// otherwise indicated in the comments. When used in the render process the +// methods of this class may only be called on the main thread. +/// +/*--cef(source=library)--*/ +class CefFrame : public virtual CefBase { + public: + /// + // True if this object is currently attached to a valid frame. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Execute undo in this frame. + /// + /*--cef()--*/ + virtual void Undo() =0; + + /// + // Execute redo in this frame. + /// + /*--cef()--*/ + virtual void Redo() =0; + + /// + // Execute cut in this frame. + /// + /*--cef()--*/ + virtual void Cut() =0; + + /// + // Execute copy in this frame. + /// + /*--cef()--*/ + virtual void Copy() =0; + + /// + // Execute paste in this frame. + /// + /*--cef()--*/ + virtual void Paste() =0; + + /// + // Execute delete in this frame. + /// + /*--cef(capi_name=del)--*/ + virtual void Delete() =0; + + /// + // Execute select all in this frame. + /// + /*--cef()--*/ + virtual void SelectAll() =0; + + /// + // Save this frame's HTML source to a temporary file and open it in the + // default text viewing application. This method can only be called from the + // browser process. + /// + /*--cef()--*/ + virtual void ViewSource() =0; + + /// + // Retrieve this frame's HTML source as a string sent to the specified + // visitor. + /// + /*--cef()--*/ + virtual void GetSource(CefRefPtr visitor) =0; + + /// + // Retrieve this frame's display text as a string sent to the specified + // visitor. + /// + /*--cef()--*/ + virtual void GetText(CefRefPtr visitor) =0; + + /// + // Load the request represented by the |request| object. + /// + /*--cef()--*/ + virtual void LoadRequest(CefRefPtr request) =0; + + /// + // Load the specified |url|. + /// + /*--cef()--*/ + virtual void LoadURL(const CefString& url) =0; + + /// + // Load the contents of |string_val| with the specified dummy |url|. |url| + // should have a standard scheme (for example, http scheme) or behaviors like + // link clicks and web security restrictions may not behave as expected. + /// + /*--cef()--*/ + virtual void LoadString(const CefString& string_val, + const CefString& url) =0; + + /// + // Execute a string of JavaScript code in this frame. The |script_url| + // parameter is the URL where the script in question can be found, if any. + // The renderer may request this URL to show the developer the source of the + // error. The |start_line| parameter is the base line number to use for error + // reporting. + /// + /*--cef(optional_param=script_url)--*/ + virtual void ExecuteJavaScript(const CefString& code, + const CefString& script_url, + int start_line) =0; + + /// + // Returns true if this is the main (top-level) frame. + /// + /*--cef()--*/ + virtual bool IsMain() =0; + + /// + // Returns true if this is the focused frame. + /// + /*--cef()--*/ + virtual bool IsFocused() =0; + + /// + // Returns the name for this frame. If the frame has an assigned name (for + // example, set via the iframe "name" attribute) then that value will be + // returned. Otherwise a unique name will be constructed based on the frame + // parent hierarchy. The main (top-level) frame will always have an empty name + // value. + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the globally unique identifier for this frame. + /// + /*--cef()--*/ + virtual int64 GetIdentifier() =0; + + /// + // Returns the parent of this frame or NULL if this is the main (top-level) + // frame. + /// + /*--cef()--*/ + virtual CefRefPtr GetParent() =0; + + /// + // Returns the URL currently loaded in this frame. + /// + /*--cef()--*/ + virtual CefString GetURL() =0; + + /// + // Returns the browser that this frame belongs to. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowser() =0; + + /// + // Get the V8 context associated with the frame. This method can only be + // called from the render process. + /// + /*--cef()--*/ + virtual CefRefPtr GetV8Context() =0; + + /// + // Visit the DOM document. This method can only be called from the render + // process. + /// + /*--cef()--*/ + virtual void VisitDOM(CefRefPtr visitor) =0; +}; + +#endif // CEF_INCLUDE_CEF_FRAME_H_ diff --git a/cefpython/cef3/include/cef_geolocation.h b/cefpython/cef3/include/cef_geolocation.h new file mode 100644 index 00000000..69c08779 --- /dev/null +++ b/cefpython/cef3/include/cef_geolocation.h @@ -0,0 +1,66 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_GEOLOCATION_H_ +#define CEF_INCLUDE_CEF_GEOLOCATION_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Implement this interface to receive geolocation updates. The methods of this +// class will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefGetGeolocationCallback : public virtual CefBase { + public: + /// + // Called with the 'best available' location information or, if the location + // update failed, with error information. + /// + /*--cef()--*/ + virtual void OnLocationUpdate(const CefGeoposition& position) =0; +}; + +/// +// Request a one-time geolocation update. This function bypasses any user +// permission checks so should only be used by code that is allowed to access +// location information. +/// +/*--cef()--*/ +bool CefGetGeolocation(CefRefPtr callback); + +#endif // CEF_INCLUDE_CEF_GEOLOCATION_H_ diff --git a/cefpython/cef3/include/cef_geolocation_handler.h b/cefpython/cef3/include/cef_geolocation_handler.h new file mode 100644 index 00000000..ea92cdd2 --- /dev/null +++ b/cefpython/cef3/include/cef_geolocation_handler.h @@ -0,0 +1,94 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ +#define CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Callback interface used for asynchronous continuation of geolocation +// permission requests. +/// +/*--cef(source=library)--*/ +class CefGeolocationCallback : public virtual CefBase { + public: + /// + // Call to allow or deny geolocation access. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(bool allow) =0; +}; + + +/// +// Implement this interface to handle events related to geolocation permission +// requests. The methods of this class will be called on the browser process IO +// thread. +/// +/*--cef(source=client)--*/ +class CefGeolocationHandler : public virtual CefBase { + public: + /// + // Called when a page requests permission to access geolocation information. + // |requesting_url| is the URL requesting permission and |request_id| is the + // unique ID for the permission request. Call CefGeolocationCallback::Continue + // to allow or deny the permission request. + /// + /*--cef()--*/ + virtual void OnRequestGeolocationPermission( + CefRefPtr browser, + const CefString& requesting_url, + int request_id, + CefRefPtr callback) { + } + + /// + // Called when a geolocation access request is canceled. |requesting_url| is + // the URL that originally requested permission and |request_id| is the unique + // ID for the permission request. + /// + /*--cef()--*/ + virtual void OnCancelGeolocationPermission( + CefRefPtr browser, + const CefString& requesting_url, + int request_id) { + } +}; + +#endif // CEF_INCLUDE_CEF_GEOLOCATION_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_jsdialog_handler.h b/cefpython/cef3/include/cef_jsdialog_handler.h new file mode 100644 index 00000000..419ba13d --- /dev/null +++ b/cefpython/cef3/include/cef_jsdialog_handler.h @@ -0,0 +1,128 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ +#define CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Callback interface used for asynchronous continuation of JavaScript dialog +// requests. +/// +/*--cef(source=library)--*/ +class CefJSDialogCallback : public virtual CefBase { + public: + /// + // Continue the JS dialog request. Set |success| to true if the OK button was + // pressed. The |user_input| value should be specified for prompt dialogs. + /// + /*--cef(capi_name=cont,optional_param=user_input)--*/ + virtual void Continue(bool success, + const CefString& user_input) =0; +}; + + +/// +// Implement this interface to handle events related to JavaScript dialogs. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefJSDialogHandler : public virtual CefBase { + public: + typedef cef_jsdialog_type_t JSDialogType; + + /// + // Called to run a JavaScript dialog. The |default_prompt_text| value will be + // specified for prompt dialogs only. Set |suppress_message| to true and + // return false to suppress the message (suppressing messages is preferable + // to immediately executing the callback as this is used to detect presumably + // malicious behavior like spamming alert messages in onbeforeunload). Set + // |suppress_message| to false and return false to use the default + // implementation (the default implementation will show one modal dialog at a + // time and suppress any additional dialog requests until the displayed dialog + // is dismissed). Return true if the application will use a custom dialog or + // if the callback has been executed immediately. Custom dialogs may be either + // modal or modeless. If a custom dialog is used the application must execute + // |callback| once the custom dialog is dismissed. + /// + /*--cef(optional_param=accept_lang,optional_param=message_text, + optional_param=default_prompt_text)--*/ + virtual bool OnJSDialog(CefRefPtr browser, + const CefString& origin_url, + const CefString& accept_lang, + JSDialogType dialog_type, + const CefString& message_text, + const CefString& default_prompt_text, + CefRefPtr callback, + bool& suppress_message) { + return false; + } + + /// + // Called to run a dialog asking the user if they want to leave a page. Return + // false to use the default dialog implementation. Return true if the + // application will use a custom dialog or if the callback has been executed + // immediately. Custom dialogs may be either modal or modeless. If a custom + // dialog is used the application must execute |callback| once the custom + // dialog is dismissed. + /// + /*--cef(optional_param=message_text)--*/ + virtual bool OnBeforeUnloadDialog(CefRefPtr browser, + const CefString& message_text, + bool is_reload, + CefRefPtr callback) { + return false; + } + + /// + // Called to cancel any pending dialogs and reset any saved dialog state. Will + // be called due to events like page navigation irregardless of whether any + // dialogs are currently pending. + /// + /*--cef()--*/ + virtual void OnResetDialogState(CefRefPtr browser) {} + + /// + // Called when the default implementation dialog is closed. + /// + /*--cef()--*/ + virtual void OnDialogClosed(CefRefPtr browser) {} +}; + +#endif // CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_keyboard_handler.h b/cefpython/cef3/include/cef_keyboard_handler.h new file mode 100644 index 00000000..55cb57ef --- /dev/null +++ b/cefpython/cef3/include/cef_keyboard_handler.h @@ -0,0 +1,74 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ +#define CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to keyboard input. The +// methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefKeyboardHandler : public virtual CefBase { + public: + // Called before a keyboard event is sent to the renderer. |event| contains + // information about the keyboard event. |os_event| is the operating system + // event message, if any. Return true if the event was handled or false + // otherwise. If the event will be handled in OnKeyEvent() as a keyboard + // shortcut set |is_keyboard_shortcut| to true and return false. + /*--cef()--*/ + virtual bool OnPreKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event, + bool* is_keyboard_shortcut) { return false; } + + /// + // Called after the renderer and JavaScript in the page has had a chance to + // handle the event. |event| contains information about the keyboard event. + // |os_event| is the operating system event message, if any. Return true if + // the keyboard event was handled or false otherwise. + /// + /*--cef()--*/ + virtual bool OnKeyEvent(CefRefPtr browser, + const CefKeyEvent& event, + CefEventHandle os_event) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_KEYBOARD_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_life_span_handler.h b/cefpython/cef3/include/cef_life_span_handler.h new file mode 100644 index 00000000..5e652716 --- /dev/null +++ b/cefpython/cef3/include/cef_life_span_handler.h @@ -0,0 +1,166 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ +#define CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +class CefClient; + +/// +// Implement this interface to handle events related to browser life span. The +// methods of this class will be called on the UI thread unless otherwise +// indicated. +/// +/*--cef(source=client)--*/ +class CefLifeSpanHandler : public virtual CefBase { + public: + /// + // Called on the IO thread before a new popup window is created. The |browser| + // and |frame| parameters represent the source of the popup request. The + // |target_url| and |target_frame_name| values may be empty if none were + // specified with the request. The |popupFeatures| structure contains + // information about the requested popup window. To allow creation of the + // popup window optionally modify |windowInfo|, |client|, |settings| and + // |no_javascript_access| and return false. To cancel creation of the popup + // window return true. The |client| and |settings| values will default to the + // source browser's values. The |no_javascript_access| value indicates whether + // the new browser window should be scriptable and in the same process as the + // source browser. + /*--cef(optional_param=target_url,optional_param=target_frame_name)--*/ + virtual bool OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) { + return false; + } + + /// + // Called after a new browser is created. + /// + /*--cef()--*/ + virtual void OnAfterCreated(CefRefPtr browser) {} + + /// + // Called when a modal window is about to display and the modal loop should + // begin running. Return false to use the default modal loop implementation or + // true to use a custom implementation. + /// + /*--cef()--*/ + virtual bool RunModal(CefRefPtr browser) { return false; } + + /// + // Called when a browser has recieved a request to close. This may result + // directly from a call to CefBrowserHost::CloseBrowser() or indirectly if the + // browser is a top-level OS window created by CEF and the user attempts to + // close the window. This method will be called after the JavaScript + // 'onunload' event has been fired. It will not be called for browsers after + // the associated OS window has been destroyed (for those browsers it is no + // longer possible to cancel the close). + // + // If CEF created an OS window for the browser returning false will send an OS + // close notification to the browser window's top-level owner (e.g. WM_CLOSE + // on Windows, performClose: on OS-X and "delete_event" on Linux). If no OS + // window exists (window rendering disabled) returning false will cause the + // browser object to be destroyed immediately. Return true if the browser is + // parented to another window and that other window needs to receive close + // notification via some non-standard technique. + // + // If an application provides its own top-level window it should handle OS + // close notifications by calling CefBrowserHost::CloseBrowser(false) instead + // of immediately closing (see the example below). This gives CEF an + // opportunity to process the 'onbeforeunload' event and optionally cancel the + // close before DoClose() is called. + // + // The CefLifeSpanHandler::OnBeforeClose() method will be called immediately + // before the browser object is destroyed. The application should only exit + // after OnBeforeClose() has been called for all existing browsers. + // + // If the browser represents a modal window and a custom modal loop + // implementation was provided in CefLifeSpanHandler::RunModal() this callback + // should be used to restore the opener window to a usable state. + // + // By way of example consider what should happen during window close when the + // browser is parented to an application-provided top-level OS window. + // 1. User clicks the window close button which sends an OS close + // notification (e.g. WM_CLOSE on Windows, performClose: on OS-X and + // "delete_event" on Linux). + // 2. Application's top-level window receives the close notification and: + // A. Calls CefBrowserHost::CloseBrowser(false). + // B. Cancels the window close. + // 3. JavaScript 'onbeforeunload' handler executes and shows the close + // confirmation dialog (which can be overridden via + // CefJSDialogHandler::OnBeforeUnloadDialog()). + // 4. User approves the close. + // 5. JavaScript 'onunload' handler executes. + // 6. Application's DoClose() handler is called. Application will: + // A. Call CefBrowserHost::ParentWindowWillClose() to notify CEF that the + // parent window will be closing. + // B. Set a flag to indicate that the next close attempt will be allowed. + // C. Return false. + // 7. CEF sends an OS close notification. + // 8. Application's top-level window receives the OS close notification and + // allows the window to close based on the flag from #6B. + // 9. Browser OS window is destroyed. + // 10. Application's CefLifeSpanHandler::OnBeforeClose() handler is called and + // the browser object is destroyed. + // 11. Application exits by calling CefQuitMessageLoop() if no other browsers + // exist. + /// + /*--cef()--*/ + virtual bool DoClose(CefRefPtr browser) { return false; } + + /// + // Called just before a browser is destroyed. Release all references to the + // browser object and do not attempt to execute any methods on the browser + // object after this callback returns. If this is a modal window and a custom + // modal loop implementation was provided in RunModal() this callback should + // be used to exit the custom modal loop. See DoClose() documentation for + // additional usage information. + /// + /*--cef()--*/ + virtual void OnBeforeClose(CefRefPtr browser) {} +}; + +#endif // CEF_INCLUDE_CEF_LIFE_SPAN_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_load_handler.h b/cefpython/cef3/include/cef_load_handler.h new file mode 100644 index 00000000..02d9d9f1 --- /dev/null +++ b/cefpython/cef3/include/cef_load_handler.h @@ -0,0 +1,107 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_LOAD_HANDLER_H_ +#define CEF_INCLUDE_CEF_LOAD_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" + +/// +// Implement this interface to handle events related to browser load status. The +// methods of this class will be called on the browser process UI thread or +// render process main thread (TID_RENDERER). +/// +/*--cef(source=client)--*/ +class CefLoadHandler : public virtual CefBase { + public: + typedef cef_errorcode_t ErrorCode; + + /// + // Called when the loading state has changed. This callback will be executed + // twice -- once when loading is initiated either programmatically or by user + // action, and once when loading is terminated due to completion, cancellation + // of failure. + /// + /*--cef()--*/ + virtual void OnLoadingStateChange(CefRefPtr browser, + bool isLoading, + bool canGoBack, + bool canGoForward) {} + + /// + // Called when the browser begins loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // may not be called for a particular frame if the load request for that frame + // fails. For notification of overall browser load status use + // OnLoadingStateChange instead. + /// + /*--cef()--*/ + virtual void OnLoadStart(CefRefPtr browser, + CefRefPtr frame) {} + + /// + // Called when the browser is done loading a frame. The |frame| value will + // never be empty -- call the IsMain() method to check if this frame is the + // main frame. Multiple frames may be loading at the same time. Sub-frames may + // start or continue loading after the main frame load has ended. This method + // will always be called for all frames irrespective of whether the request + // completes successfully. + /// + /*--cef()--*/ + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) {} + + /// + // Called when the resource load for a navigation fails or is canceled. + // |errorCode| is the error code number, |errorText| is the error text and + // |failedUrl| is the URL that failed to load. See net\base\net_error_list.h + // for complete descriptions of the error codes. + /// + /*--cef(optional_param=errorText)--*/ + virtual void OnLoadError(CefRefPtr browser, + CefRefPtr frame, + ErrorCode errorCode, + const CefString& errorText, + const CefString& failedUrl) {} +}; + +#endif // CEF_INCLUDE_CEF_LOAD_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_menu_model.h b/cefpython/cef3/include/cef_menu_model.h new file mode 100644 index 00000000..84728c58 --- /dev/null +++ b/cefpython/cef3/include/cef_menu_model.h @@ -0,0 +1,402 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_MENU_MODEL_H_ +#define CEF_INCLUDE_CEF_MENU_MODEL_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Supports creation and modification of menus. See cef_menu_id_t for the +// command ids that have default implementations. All user-defined command ids +// should be between MENU_ID_USER_FIRST and MENU_ID_USER_LAST. The methods of +// this class can only be accessed on the browser process the UI thread. +/// +/*--cef(source=library)--*/ +class CefMenuModel : public virtual CefBase { + public: + typedef cef_menu_item_type_t MenuItemType; + + /// + // Clears the menu. Returns true on success. + /// + /*--cef()--*/ + virtual bool Clear() =0; + + /// + // Returns the number of items in this menu. + /// + /*--cef()--*/ + virtual int GetCount() =0; + + // + // Add a separator to the menu. Returns true on success. + /// + /*--cef()--*/ + virtual bool AddSeparator() =0; + + // + // Add an item to the menu. Returns true on success. + /// + /*--cef()--*/ + virtual bool AddItem(int command_id, + const CefString& label) =0; + + // + // Add a check item to the menu. Returns true on success. + /// + /*--cef()--*/ + virtual bool AddCheckItem(int command_id, + const CefString& label) =0; + // + // Add a radio item to the menu. Only a single item with the specified + // |group_id| can be checked at a time. Returns true on success. + /// + /*--cef()--*/ + virtual bool AddRadioItem(int command_id, + const CefString& label, + int group_id) =0; + + // + // Add a sub-menu to the menu. The new sub-menu is returned. + /// + /*--cef()--*/ + virtual CefRefPtr AddSubMenu(int command_id, + const CefString& label) =0; + + // + // Insert a separator in the menu at the specified |index|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool InsertSeparatorAt(int index) =0; + + // + // Insert an item in the menu at the specified |index|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool InsertItemAt(int index, + int command_id, + const CefString& label) =0; + + // + // Insert a check item in the menu at the specified |index|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool InsertCheckItemAt(int index, + int command_id, + const CefString& label) =0; + + // + // Insert a radio item in the menu at the specified |index|. Only a single + // item with the specified |group_id| can be checked at a time. Returns true + // on success. + /// + /*--cef()--*/ + virtual bool InsertRadioItemAt(int index, + int command_id, + const CefString& label, + int group_id) =0; + + // + // Insert a sub-menu in the menu at the specified |index|. The new sub-menu + // is returned. + /// + /*--cef()--*/ + virtual CefRefPtr InsertSubMenuAt(int index, + int command_id, + const CefString& label) =0; + + /// + // Removes the item with the specified |command_id|. Returns true on success. + /// + /*--cef()--*/ + virtual bool Remove(int command_id) =0; + + /// + // Removes the item at the specified |index|. Returns true on success. + /// + /*--cef()--*/ + virtual bool RemoveAt(int index) =0; + + /// + // Returns the index associated with the specified |command_id| or -1 if not + // found due to the command id not existing in the menu. + /// + /*--cef()--*/ + virtual int GetIndexOf(int command_id) =0; + + /// + // Returns the command id at the specified |index| or -1 if not found due to + // invalid range or the index being a separator. + /// + /*--cef()--*/ + virtual int GetCommandIdAt(int index) =0; + + /// + // Sets the command id at the specified |index|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetCommandIdAt(int index, int command_id) =0; + + /// + // Returns the label for the specified |command_id| or empty if not found. + /// + /*--cef()--*/ + virtual CefString GetLabel(int command_id) =0; + + /// + // Returns the label at the specified |index| or empty if not found due to + // invalid range or the index being a separator. + /// + /*--cef()--*/ + virtual CefString GetLabelAt(int index) =0; + + /// + // Sets the label for the specified |command_id|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetLabel(int command_id, const CefString& label) =0; + + /// + // Set the label at the specified |index|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetLabelAt(int index, const CefString& label) =0; + + /// + // Returns the item type for the specified |command_id|. + /// + /*--cef(default_retval=MENUITEMTYPE_NONE)--*/ + virtual MenuItemType GetType(int command_id) =0; + + /// + // Returns the item type at the specified |index|. + /// + /*--cef(default_retval=MENUITEMTYPE_NONE)--*/ + virtual MenuItemType GetTypeAt(int index) =0; + + /// + // Returns the group id for the specified |command_id| or -1 if invalid. + /// + /*--cef()--*/ + virtual int GetGroupId(int command_id) =0; + + /// + // Returns the group id at the specified |index| or -1 if invalid. + /// + /*--cef()--*/ + virtual int GetGroupIdAt(int index) =0; + + /// + // Sets the group id for the specified |command_id|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetGroupId(int command_id, int group_id) =0; + + /// + // Sets the group id at the specified |index|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetGroupIdAt(int index, int group_id) =0; + + /// + // Returns the submenu for the specified |command_id| or empty if invalid. + /// + /*--cef()--*/ + virtual CefRefPtr GetSubMenu(int command_id) =0; + + /// + // Returns the submenu at the specified |index| or empty if invalid. + /// + /*--cef()--*/ + virtual CefRefPtr GetSubMenuAt(int index) =0; + + // + // Returns true if the specified |command_id| is visible. + /// + /*--cef()--*/ + virtual bool IsVisible(int command_id) =0; + + // + // Returns true if the specified |index| is visible. + /// + /*--cef()--*/ + virtual bool IsVisibleAt(int index) =0; + + // + // Change the visibility of the specified |command_id|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool SetVisible(int command_id, bool visible) =0; + + // + // Change the visibility at the specified |index|. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetVisibleAt(int index, bool visible) =0; + + // + // Returns true if the specified |command_id| is enabled. + /// + /*--cef()--*/ + virtual bool IsEnabled(int command_id) =0; + + // + // Returns true if the specified |index| is enabled. + /// + /*--cef()--*/ + virtual bool IsEnabledAt(int index) =0; + + // + // Change the enabled status of the specified |command_id|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool SetEnabled(int command_id, bool enabled) =0; + + // + // Change the enabled status at the specified |index|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool SetEnabledAt(int index, bool enabled) =0; + + // + // Returns true if the specified |command_id| is checked. Only applies to + // check and radio items. + /// + /*--cef()--*/ + virtual bool IsChecked(int command_id) =0; + + // + // Returns true if the specified |index| is checked. Only applies to check + // and radio items. + /// + /*--cef()--*/ + virtual bool IsCheckedAt(int index) =0; + + // + // Check the specified |command_id|. Only applies to check and radio items. + // Returns true on success. + /// + /*--cef()--*/ + virtual bool SetChecked(int command_id, bool checked) =0; + + // + // Check the specified |index|. Only applies to check and radio items. Returns + // true on success. + /// + /*--cef()--*/ + virtual bool SetCheckedAt(int index, bool checked) =0; + + // + // Returns true if the specified |command_id| has a keyboard accelerator + // assigned. + /// + /*--cef()--*/ + virtual bool HasAccelerator(int command_id) =0; + + // + // Returns true if the specified |index| has a keyboard accelerator assigned. + /// + /*--cef()--*/ + virtual bool HasAcceleratorAt(int index) =0; + + // + // Set the keyboard accelerator for the specified |command_id|. |key_code| can + // be any virtual key or character value. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetAccelerator(int command_id, + int key_code, + bool shift_pressed, + bool ctrl_pressed, + bool alt_pressed) =0; + + // + // Set the keyboard accelerator at the specified |index|. |key_code| can be + // any virtual key or character value. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetAcceleratorAt(int index, + int key_code, + bool shift_pressed, + bool ctrl_pressed, + bool alt_pressed) =0; + + // + // Remove the keyboard accelerator for the specified |command_id|. Returns + // true on success. + /// + /*--cef()--*/ + virtual bool RemoveAccelerator(int command_id) =0; + + // + // Remove the keyboard accelerator at the specified |index|. Returns true on + // success. + /// + /*--cef()--*/ + virtual bool RemoveAcceleratorAt(int index) =0; + + // + // Retrieves the keyboard accelerator for the specified |command_id|. Returns + // true on success. + /// + /*--cef()--*/ + virtual bool GetAccelerator(int command_id, + int& key_code, + bool& shift_pressed, + bool& ctrl_pressed, + bool& alt_pressed) =0; + + // + // Retrieves the keyboard accelerator for the specified |index|. Returns true + // on success. + /// + /*--cef()--*/ + virtual bool GetAcceleratorAt(int index, + int& key_code, + bool& shift_pressed, + bool& ctrl_pressed, + bool& alt_pressed) =0; +}; + +#endif // CEF_INCLUDE_CEF_MENU_MODEL_H_ diff --git a/cefpython/cef3/include/cef_origin_whitelist.h b/cefpython/cef3/include/cef_origin_whitelist.h new file mode 100644 index 00000000..7fed3453 --- /dev/null +++ b/cefpython/cef3/include/cef_origin_whitelist.h @@ -0,0 +1,103 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ +#define CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ +#pragma once + +#include "include/cef_base.h" + + +/// +// Add an entry to the cross-origin access whitelist. +// +// The same-origin policy restricts how scripts hosted from different origins +// (scheme + domain + port) can communicate. By default, scripts can only access +// resources with the same origin. Scripts hosted on the HTTP and HTTPS schemes +// (but no other schemes) can use the "Access-Control-Allow-Origin" header to +// allow cross-origin requests. For example, https://source.example.com can make +// XMLHttpRequest requests on http://target.example.com if the +// http://target.example.com request returns an "Access-Control-Allow-Origin: +// https://source.example.com" response header. +// +// Scripts in separate frames or iframes and hosted from the same protocol and +// domain suffix can execute cross-origin JavaScript if both pages set the +// document.domain value to the same domain suffix. For example, +// scheme://foo.example.com and scheme://bar.example.com can communicate using +// JavaScript if both domains set document.domain="example.com". +// +// This method is used to allow access to origins that would otherwise violate +// the same-origin policy. Scripts hosted underneath the fully qualified +// |source_origin| URL (like http://www.example.com) will be allowed access to +// all resources hosted on the specified |target_protocol| and |target_domain|. +// If |target_domain| is non-empty and |allow_target_subdomains| if false only +// exact domain matches will be allowed. If |target_domain| contains a top- +// level domain component (like "example.com") and |allow_target_subdomains| is +// true sub-domain matches will be allowed. If |target_domain| is empty and +// |allow_target_subdomains| if true all domains and IP addresses will be +// allowed. +// +// This method cannot be used to bypass the restrictions on local or display +// isolated schemes. See the comments on CefRegisterCustomScheme for more +// information. +// +// This function may be called on any thread. Returns false if |source_origin| +// is invalid or the whitelist cannot be accessed. +/// +/*--cef(optional_param=target_domain)--*/ +bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin, + const CefString& target_protocol, + const CefString& target_domain, + bool allow_target_subdomains); + +/// +// Remove an entry from the cross-origin access whitelist. Returns false if +// |source_origin| is invalid or the whitelist cannot be accessed. +/// +/*--cef(optional_param=target_domain)--*/ +bool CefRemoveCrossOriginWhitelistEntry(const CefString& source_origin, + const CefString& target_protocol, + const CefString& target_domain, + bool allow_target_subdomains); + +/// +// Remove all entries from the cross-origin access whitelist. Returns false if +// the whitelist cannot be accessed. +/// +/*--cef()--*/ +bool CefClearCrossOriginWhitelist(); + +#endif // CEF_INCLUDE_CEF_ORIGIN_WHITELIST_H_ diff --git a/cefpython/cef3/include/cef_path_util.h b/cefpython/cef3/include/cef_path_util.h new file mode 100644 index 00000000..552f4ba5 --- /dev/null +++ b/cefpython/cef3/include/cef_path_util.h @@ -0,0 +1,52 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_PATH_UTIL_H_ +#define CEF_INCLUDE_CEF_PATH_UTIL_H_ +#pragma once + +#include "include/cef_base.h" + +typedef cef_path_key_t PathKey; + +/// +// Retrieve the path associated with the specified |key|. Returns true on +// success. Can be called on any thread in the browser process. +/// +/*--cef()--*/ +bool CefGetPath(PathKey key, CefString& path); + +#endif // CEF_INCLUDE_CEF_PATH_UTIL_H_ diff --git a/cefpython/cef3/include/cef_process_message.h b/cefpython/cef3/include/cef_process_message.h new file mode 100644 index 00000000..1e27bd68 --- /dev/null +++ b/cefpython/cef3/include/cef_process_message.h @@ -0,0 +1,91 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_MESSAGE_H_ +#define CEF_INCLUDE_CEF_MESSAGE_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_values.h" + +typedef cef_process_id_t CefProcessId; + +/// +// Class representing a message. Can be used on any process and thread. +/// +/*--cef(source=library)--*/ +class CefProcessMessage : public virtual CefBase { + public: + /// + // Create a new CefProcessMessage object with the specified name. + /// + /*--cef()--*/ + static CefRefPtr Create(const CefString& name); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // function returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if the values of this object are read-only. Some APIs may + // expose read-only objects. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Returns a writable copy of this object. + /// + /*--cef()--*/ + virtual CefRefPtr Copy() =0; + + /// + // Returns the message name. + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the list of arguments. + /// + /*--cef()--*/ + virtual CefRefPtr GetArgumentList() =0; +}; + +#endif // CEF_INCLUDE_CEF_MESSAGE_H_ diff --git a/cefpython/cef3/include/cef_process_util.h b/cefpython/cef3/include/cef_process_util.h new file mode 100644 index 00000000..4fce778e --- /dev/null +++ b/cefpython/cef3/include/cef_process_util.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_PROCESS_UTIL_H_ +#define CEF_INCLUDE_CEF_PROCESS_UTIL_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_command_line.h" + +/// +// Launches the process specified via |command_line|. Returns true upon +// success. Must be called on the browser process TID_PROCESS_LAUNCHER thread. +// +// Unix-specific notes: +// - All file descriptors open in the parent process will be closed in the +// child process except for stdin, stdout, and stderr. +// - If the first argument on the command line does not contain a slash, +// PATH will be searched. (See man execvp.) +/// +/*--cef()--*/ +bool CefLaunchProcess(CefRefPtr command_line); + +#endif // CEF_INCLUDE_CEF_PROCESS_UTIL_H_ diff --git a/cefpython/cef3/include/cef_render_handler.h b/cefpython/cef3/include/cef_render_handler.h new file mode 100644 index 00000000..c0997247 --- /dev/null +++ b/cefpython/cef3/include/cef_render_handler.h @@ -0,0 +1,138 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RENDER_HANDLER_H_ +#define CEF_INCLUDE_CEF_RENDER_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include + +/// +// Implement this interface to handle events when window rendering is disabled. +// The methods of this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefRenderHandler : public virtual CefBase { + public: + typedef cef_paint_element_type_t PaintElementType; + typedef std::vector RectList; + + /// + // Called to retrieve the root window rectangle in screen coordinates. Return + // true if the rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetRootScreenRect(CefRefPtr browser, + CefRect& rect) { return false; } + + /// + // Called to retrieve the view rectangle which is relative to screen + // coordinates. Return true if the rectangle was provided. + /// + /*--cef()--*/ + virtual bool GetViewRect(CefRefPtr browser, CefRect& rect) =0; + + /// + // Called to retrieve the translation from view coordinates to actual screen + // coordinates. Return true if the screen coordinates were provided. + /// + /*--cef()--*/ + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { return false; } + + /// + // Called to allow the client to fill in the CefScreenInfo object with + // appropriate values. Return true if the |screen_info| structure has been + // modified. + // + // If the screen info rectangle is left empty the rectangle from GetViewRect + // will be used. If the rectangle is still empty or invalid popups may not be + // drawn correctly. + /// + /*--cef()--*/ + virtual bool GetScreenInfo(CefRefPtr browser, + CefScreenInfo& screen_info) { return false; } + + /// + // Called when the browser wants to show or hide the popup widget. The popup + // should be shown if |show| is true and hidden if |show| is false. + /// + /*--cef()--*/ + virtual void OnPopupShow(CefRefPtr browser, + bool show) {} + + /// + // Called when the browser wants to move or resize the popup widget. |rect| + // contains the new location and size. + /// + /*--cef()--*/ + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) {} + + /// + // Called when an element should be painted. |type| indicates whether the + // element is the view or the popup widget. |buffer| contains the pixel data + // for the whole image. |dirtyRects| contains the set of rectangles that need + // to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes + // in size and represents a BGRA image with an upper-left origin. + /// + /*--cef()--*/ + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) =0; + + /// + // Called when the browser window's cursor has changed. + /// + /*--cef()--*/ + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) {} + + /// + // Called when the scroll offset has changed. + /// + /*--cef()--*/ + virtual void OnScrollOffsetChanged(CefRefPtr browser) {} +}; + +#endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_render_process_handler.h b/cefpython/cef3/include/cef_render_process_handler.h new file mode 100644 index 00000000..98ab391b --- /dev/null +++ b/cefpython/cef3/include/cef_render_process_handler.h @@ -0,0 +1,168 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RENDER_PROCESS_HANDLER_H_ +#define CEF_INCLUDE_CEF_RENDER_PROCESS_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_dom.h" +#include "include/cef_frame.h" +#include "include/cef_load_handler.h" +#include "include/cef_process_message.h" +#include "include/cef_v8.h" +#include "include/cef_values.h" + +/// +// Class used to implement render process callbacks. The methods of this class +// will be called on the render process main thread (TID_RENDERER) unless +// otherwise indicated. +/// +/*--cef(source=client)--*/ +class CefRenderProcessHandler : public virtual CefBase { + public: + typedef cef_navigation_type_t NavigationType; + + /// + // Called after the render process main thread has been created. |extra_info| + // is a read-only value originating from + // CefBrowserProcessHandler::OnRenderProcessThreadCreated(). Do not keep a + // reference to |extra_info| outside of this method. + /// + /*--cef()--*/ + virtual void OnRenderThreadCreated(CefRefPtr extra_info) {} + + /// + // Called after WebKit has been initialized. + /// + /*--cef()--*/ + virtual void OnWebKitInitialized() {} + + /// + // Called after a browser has been created. When browsing cross-origin a new + // browser will be created before the old browser with the same identifier is + // destroyed. + /// + /*--cef()--*/ + virtual void OnBrowserCreated(CefRefPtr browser) {} + + /// + // Called before a browser is destroyed. + /// + /*--cef()--*/ + virtual void OnBrowserDestroyed(CefRefPtr browser) {} + + /// + // Return the handler for browser load status events. + /// + /*--cef()--*/ + virtual CefRefPtr GetLoadHandler() { + return NULL; + } + + /// + // Called before browser navigation. Return true to cancel the navigation or + // false to allow the navigation to proceed. The |request| object cannot be + // modified in this callback. + /// + /*--cef()--*/ + virtual bool OnBeforeNavigation(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + NavigationType navigation_type, + bool is_redirect) { return false; } + + /// + // Called immediately after the V8 context for a frame has been created. To + // retrieve the JavaScript 'window' object use the CefV8Context::GetGlobal() + // method. V8 handles can only be accessed from the thread on which they are + // created. A task runner for posting tasks on the associated thread can be + // retrieved via the CefV8Context::GetTaskRunner() method. + /// + /*--cef()--*/ + virtual void OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) {} + + /// + // Called immediately before the V8 context for a frame is released. No + // references to the context should be kept after this method is called. + /// + /*--cef()--*/ + virtual void OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) {} + + /// + // Called for global uncaught exceptions in a frame. Execution of this + // callback is disabled by default. To enable set + // CefSettings.uncaught_exception_stack_size > 0. + /// + /*--cef()--*/ + virtual void OnUncaughtException(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) {} + + /// + // Called when a new node in the the browser gets focus. The |node| value may + // be empty if no specific node has gained focus. The node object passed to + // this method represents a snapshot of the DOM at the time this method is + // executed. DOM objects are only valid for the scope of this method. Do not + // keep references to or attempt to access any DOM objects outside the scope + // of this method. + /// + /*--cef(optional_param=frame,optional_param=node)--*/ + virtual void OnFocusedNodeChanged(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr node) {} + + /// + // Called when a new message is received from a different process. Return true + // if the message was handled or false otherwise. Do not keep a reference to + // or attempt to access the message outside of this callback. + /// + /*--cef()--*/ + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + return false; + } +}; + +#endif // CEF_INCLUDE_CEF_RENDER_PROCESS_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_request.h b/cefpython/cef3/include/cef_request.h new file mode 100644 index 00000000..da9ec430 --- /dev/null +++ b/cefpython/cef3/include/cef_request.h @@ -0,0 +1,297 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_H_ +#define CEF_INCLUDE_CEF_REQUEST_H_ +#pragma once + +#include "include/cef_base.h" +#include +#include + +class CefPostData; +class CefPostDataElement; + +/// +// Class used to represent a web request. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefRequest : public virtual CefBase { + public: + typedef std::multimap HeaderMap; + typedef cef_resource_type_t ResourceType; + typedef cef_transition_type_t TransitionType; + + /// + // Create a new CefRequest object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Get the fully qualified URL. + /// + /*--cef()--*/ + virtual CefString GetURL() =0; + + /// + // Set the fully qualified URL. + /// + /*--cef()--*/ + virtual void SetURL(const CefString& url) =0; + + /// + // Get the request method type. The value will default to POST if post data + // is provided and GET otherwise. + /// + /*--cef()--*/ + virtual CefString GetMethod() =0; + + /// + // Set the request method type. + /// + /*--cef()--*/ + virtual void SetMethod(const CefString& method) =0; + + /// + // Get the post data. + /// + /*--cef()--*/ + virtual CefRefPtr GetPostData() =0; + + /// + // Set the post data. + /// + /*--cef()--*/ + virtual void SetPostData(CefRefPtr postData) =0; + + /// + // Get the header values. + /// + /*--cef()--*/ + virtual void GetHeaderMap(HeaderMap& headerMap) =0; + + /// + // Set the header values. + /// + /*--cef()--*/ + virtual void SetHeaderMap(const HeaderMap& headerMap) =0; + + /// + // Set all values at one time. + /// + /*--cef(optional_param=postData)--*/ + virtual void Set(const CefString& url, + const CefString& method, + CefRefPtr postData, + const HeaderMap& headerMap) =0; + + /// + // Get the flags used in combination with CefURLRequest. See + // cef_urlrequest_flags_t for supported values. + /// + /*--cef(default_retval=UR_FLAG_NONE)--*/ + virtual int GetFlags() =0; + + /// + // Set the flags used in combination with CefURLRequest. See + // cef_urlrequest_flags_t for supported values. + /// + /*--cef()--*/ + virtual void SetFlags(int flags) =0; + + /// + // Set the URL to the first party for cookies used in combination with + // CefURLRequest. + /// + /*--cef()--*/ + virtual CefString GetFirstPartyForCookies() =0; + + /// + // Get the URL to the first party for cookies used in combination with + // CefURLRequest. + /// + /*--cef()--*/ + virtual void SetFirstPartyForCookies(const CefString& url) =0; + + /// + // Get the resource type for this request. Accurate resource type information + // may only be available in the browser process. + /// + /*--cef(default_retval=RT_SUB_RESOURCE)--*/ + virtual ResourceType GetResourceType() =0; + + /// + // Get the transition type for this request. Only available in the browser + // process and only applies to requests that represent a main frame or + // sub-frame navigation. + /// + /*--cef(default_retval=TT_EXPLICIT)--*/ + virtual TransitionType GetTransitionType() =0; +}; + + +/// +// Class used to represent post data for a web request. The methods of this +// class may be called on any thread. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefPostData : public virtual CefBase { + public: + typedef std::vector > ElementVector; + + /// + // Create a new CefPostData object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Returns the number of existing post data elements. + /// + /*--cef()--*/ + virtual size_t GetElementCount() =0; + + /// + // Retrieve the post data elements. + /// + /*--cef(count_func=elements:GetElementCount)--*/ + virtual void GetElements(ElementVector& elements) =0; + + /// + // Remove the specified post data element. Returns true if the removal + // succeeds. + /// + /*--cef()--*/ + virtual bool RemoveElement(CefRefPtr element) =0; + + /// + // Add the specified post data element. Returns true if the add succeeds. + /// + /*--cef()--*/ + virtual bool AddElement(CefRefPtr element) =0; + + /// + // Remove all existing post data elements. + /// + /*--cef()--*/ + virtual void RemoveElements() =0; +}; + + +/// +// Class used to represent a single element in the request post data. The +// methods of this class may be called on any thread. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefPostDataElement : public virtual CefBase { + public: + /// + // Post data elements may represent either bytes or files. + /// + typedef cef_postdataelement_type_t Type; + + /// + // Create a new CefPostDataElement object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Remove all contents from the post data element. + /// + /*--cef()--*/ + virtual void SetToEmpty() =0; + + /// + // The post data element will represent a file. + /// + /*--cef()--*/ + virtual void SetToFile(const CefString& fileName) =0; + + /// + // The post data element will represent bytes. The bytes passed + // in will be copied. + /// + /*--cef()--*/ + virtual void SetToBytes(size_t size, const void* bytes) =0; + + /// + // Return the type of this post data element. + /// + /*--cef(default_retval=PDE_TYPE_EMPTY)--*/ + virtual Type GetType() =0; + + /// + // Return the file name. + /// + /*--cef()--*/ + virtual CefString GetFile() =0; + + /// + // Return the number of bytes. + /// + /*--cef()--*/ + virtual size_t GetBytesCount() =0; + + /// + // Read up to |size| bytes into |bytes| and return the number of bytes + // actually read. + /// + /*--cef()--*/ + virtual size_t GetBytes(size_t size, void* bytes) =0; +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_H_ diff --git a/cefpython/cef3/include/cef_request_context.h b/cefpython/cef3/include/cef_request_context.h new file mode 100644 index 00000000..32495a95 --- /dev/null +++ b/cefpython/cef3/include/cef_request_context.h @@ -0,0 +1,94 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_ +#define CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_ +#pragma once + +#include "include/cef_request_context_handler.h" + +/// +// A request context provides request handling for a set of related browser +// objects. A request context is specified when creating a new browser object +// via the CefBrowserHost static factory methods. Browser objects with different +// request contexts will never be hosted in the same render process. Browser +// objects with the same request context may or may not be hosted in the same +// render process depending on the process model. Browser objects created +// indirectly via the JavaScript window.open function or targeted links will +// share the same render process and the same request context as the source +// browser. When running in single-process mode there is only a single render +// process (the main process) and so all browsers created in single-process mode +// will share the same request context. This will be the first request context +// passed into a CefBrowserHost static factory method and all other request +// context objects will be ignored. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefRequestContext : public virtual CefBase { + public: + /// + // Returns the global context object. + /// + /*--cef()--*/ + static CefRefPtr GetGlobalContext(); + + /// + // Creates a new context object with the specified handler. + /// + /*--cef(optional_param=handler)--*/ + static CefRefPtr CreateContext( + CefRefPtr handler); + + /// + // Returns true if this object is pointing to the same context as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr other) =0; + + /// + // Returns true if this object is the global context. + /// + /*--cef()--*/ + virtual bool IsGlobal() =0; + + /// + // Returns the handler for this context if any. + /// + /*--cef()--*/ + virtual CefRefPtr GetHandler() =0; +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_ diff --git a/cefpython/cef3/include/cef_request_context_handler.h b/cefpython/cef3/include/cef_request_context_handler.h new file mode 100644 index 00000000..f77259ef --- /dev/null +++ b/cefpython/cef3/include/cef_request_context_handler.h @@ -0,0 +1,58 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_CONTEXT_HANDLER_H_ +#define CEF_INCLUDE_CEF_REQUEST_CONTEXT_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_cookie.h" + +/// +// Implement this interface to provide handler implementations. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefRequestContextHandler : public virtual CefBase { + public: + /// + // Called on the IO thread to retrieve the cookie manager. The global cookie + // manager will be used if this method returns NULL. + /// + /*--cef()--*/ + virtual CefRefPtr GetCookieManager() { return NULL; } +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_request_handler.h b/cefpython/cef3/include/cef_request_handler.h new file mode 100644 index 00000000..b52b6242 --- /dev/null +++ b/cefpython/cef3/include/cef_request_handler.h @@ -0,0 +1,245 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ +#define CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ +#pragma once + +#include "include/cef_auth_callback.h" +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include "include/cef_resource_handler.h" +#include "include/cef_response.h" +#include "include/cef_request.h" +#include "include/cef_web_plugin.h" + +/// +// Callback interface used for asynchronous continuation of quota requests. +/// +/*--cef(source=library)--*/ +class CefQuotaCallback : public virtual CefBase { + public: + /// + // Continue the quota request. If |allow| is true the request will be + // allowed. Otherwise, the request will be denied. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(bool allow) =0; + + /// + // Cancel the quota request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + + +/// +// Callback interface used for asynchronous continuation of url requests when +// invalid SSL certificates are encountered. +/// +/*--cef(source=library)--*/ +class CefAllowCertificateErrorCallback : public virtual CefBase { + public: + /// + // Continue the url request. If |allow| is true the request will be + // continued. Otherwise, the request will be canceled. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(bool allow) =0; +}; + + +/// +// Implement this interface to handle events related to browser requests. The +// methods of this class will be called on the thread indicated. +/// +/*--cef(source=client)--*/ +class CefRequestHandler : public virtual CefBase { + public: + typedef cef_termination_status_t TerminationStatus; + + /// + // Called on the UI thread before browser navigation. Return true to cancel + // the navigation or false to allow the navigation to proceed. The |request| + // object cannot be modified in this callback. + // CefLoadHandler::OnLoadingStateChange will be called twice in all cases. + // If the navigation is allowed CefLoadHandler::OnLoadStart and + // CefLoadHandler::OnLoadEnd will be called. If the navigation is canceled + // CefLoadHandler::OnLoadError will be called with an |errorCode| value of + // ERR_ABORTED. + /// + /*--cef()--*/ + virtual bool OnBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + bool is_redirect) { + return false; + } + + /// + // Called on the IO thread before a resource request is loaded. The |request| + // object may be modified. To cancel the request return true otherwise return + // false. + /// + /*--cef()--*/ + virtual bool OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) { + return false; + } + + /// + // Called on the IO thread before a resource is loaded. To allow the resource + // to load normally return NULL. To specify a handler for the resource return + // a CefResourceHandler object. The |request| object should not be modified in + // this callback. + /// + /*--cef()--*/ + virtual CefRefPtr GetResourceHandler( + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) { + return NULL; + } + + /// + // Called on the IO thread when a resource load is redirected. The |old_url| + // parameter will contain the old URL. The |new_url| parameter will contain + // the new URL and can be changed if desired. + /// + /*--cef()--*/ + virtual void OnResourceRedirect(CefRefPtr browser, + CefRefPtr frame, + const CefString& old_url, + CefString& new_url) {} + + /// + // Called on the IO thread when the browser needs credentials from the user. + // |isProxy| indicates whether the host is a proxy server. |host| contains the + // hostname and |port| contains the port number. Return true to continue the + // request and call CefAuthCallback::Continue() when the authentication + // information is available. Return false to cancel the request. + /// + /*--cef(optional_param=realm)--*/ + virtual bool GetAuthCredentials(CefRefPtr browser, + CefRefPtr frame, + bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) { + return false; + } + + /// + // Called on the IO thread when JavaScript requests a specific storage quota + // size via the webkitStorageInfo.requestQuota function. |origin_url| is the + // origin of the page making the request. |new_size| is the requested quota + // size in bytes. Return true and call CefQuotaCallback::Continue() either in + // this method or at a later time to grant or deny the request. Return false + // to cancel the request. + /// + /*--cef(optional_param=realm)--*/ + virtual bool OnQuotaRequest(CefRefPtr browser, + const CefString& origin_url, + int64 new_size, + CefRefPtr callback) { + return false; + } + + /// + // Called on the UI thread to handle requests for URLs with an unknown + // protocol component. Set |allow_os_execution| to true to attempt execution + // via the registered OS protocol handler, if any. + // SECURITY WARNING: YOU SHOULD USE THIS METHOD TO ENFORCE RESTRICTIONS BASED + // ON SCHEME, HOST OR OTHER URL ANALYSIS BEFORE ALLOWING OS EXECUTION. + /// + /*--cef()--*/ + virtual void OnProtocolExecution(CefRefPtr browser, + const CefString& url, + bool& allow_os_execution) {} + + /// + // Called on the UI thread to handle requests for URLs with an invalid + // SSL certificate. Return true and call CefAllowCertificateErrorCallback:: + // Continue() either in this method or at a later time to continue or cancel + // the request. Return false to cancel the request immediately. If |callback| + // is empty the error cannot be recovered from and the request will be + // canceled automatically. If CefSettings.ignore_certificate_errors is set + // all invalid certificates will be accepted without calling this method. + /// + /*--cef()--*/ + virtual bool OnCertificateError( + cef_errorcode_t cert_error, + const CefString& request_url, + CefRefPtr callback) { + return false; + } + + /// + // Called on the browser process IO thread before a plugin is loaded. Return + // true to block loading of the plugin. + /// + /*--cef(optional_param=url,optional_param=policy_url)--*/ + virtual bool OnBeforePluginLoad(CefRefPtr browser, + const CefString& url, + const CefString& policy_url, + CefRefPtr info) { + return false; + } + + /// + // Called on the browser process UI thread when a plugin has crashed. + // |plugin_path| is the path of the plugin that crashed. + /// + /*--cef()--*/ + virtual void OnPluginCrashed(CefRefPtr browser, + const CefString& plugin_path) {} + + /// + // Called on the browser process UI thread when the render process + // terminates unexpectedly. |status| indicates how the process + // terminated. + /// + /*--cef()--*/ + virtual void OnRenderProcessTerminated(CefRefPtr browser, + TerminationStatus status) {} +}; + +#endif // CEF_INCLUDE_CEF_REQUEST_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_resource_bundle_handler.h b/cefpython/cef3/include/cef_resource_bundle_handler.h new file mode 100644 index 00000000..2cd39a5e --- /dev/null +++ b/cefpython/cef3/include/cef_resource_bundle_handler.h @@ -0,0 +1,73 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ +#define CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Class used to implement a custom resource bundle interface. The methods of +// this class may be called on multiple threads. +/// +/*--cef(source=client)--*/ +class CefResourceBundleHandler : public virtual CefBase { + public: + /// + // Called to retrieve a localized translation for the string specified by + // |message_id|. To provide the translation set |string| to the translation + // string and return true. To use the default translation return false. + // Supported message IDs are listed in cef_pack_strings.h. + /// + /*--cef()--*/ + virtual bool GetLocalizedString(int message_id, + CefString& string) =0; + + /// + // Called to retrieve data for the resource specified by |resource_id|. To + // provide the resource data set |data| and |data_size| to the data pointer + // and size respectively and return true. To use the default resource data + // return false. The resource data will not be copied and must remain resident + // in memory. Supported resource IDs are listed in cef_pack_resources.h. + /// + /*--cef()--*/ + virtual bool GetDataResource(int resource_id, + void*& data, + size_t& data_size) =0; +}; + +#endif // CEF_INCLUDE_CEF_RESOURCE_BUNDLE_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_resource_handler.h b/cefpython/cef3/include/cef_resource_handler.h new file mode 100644 index 00000000..57c8b7fc --- /dev/null +++ b/cefpython/cef3/include/cef_resource_handler.h @@ -0,0 +1,116 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESOURCE_HANDLER_H_ +#define CEF_INCLUDE_CEF_RESOURCE_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_callback.h" +#include "include/cef_cookie.h" +#include "include/cef_request.h" +#include "include/cef_response.h" + +/// +// Class used to implement a custom request handler interface. The methods of +// this class will always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefResourceHandler : public virtual CefBase { + public: + /// + // Begin processing the request. To handle the request return true and call + // CefCallback::Continue() once the response header information is available + // (CefCallback::Continue() can also be called from inside this method if + // header information is available immediately). To cancel the request return + // false. + /// + /*--cef()--*/ + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) =0; + + /// + // Retrieve response header information. If the response length is not known + // set |response_length| to -1 and ReadResponse() will be called until it + // returns false. If the response length is known set |response_length| + // to a positive value and ReadResponse() will be called until it returns + // false or the specified number of bytes have been read. Use the |response| + // object to set the mime type, http status code and other optional header + // values. To redirect the request to a new URL set |redirectUrl| to the new + // URL. + /// + /*--cef()--*/ + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) =0; + + /// + // Read response data. If data is available immediately copy up to + // |bytes_to_read| bytes into |data_out|, set |bytes_read| to the number of + // bytes copied, and return true. To read the data at a later time set + // |bytes_read| to 0, return true and call CefCallback::Continue() when the + // data is available. To indicate response completion return false. + /// + /*--cef()--*/ + virtual bool ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) =0; + + /// + // Return true if the specified cookie can be sent with the request or false + // otherwise. If false is returned for any cookie then no cookies will be sent + // with the request. + /// + /*--cef()--*/ + virtual bool CanGetCookie(const CefCookie& cookie) { return true; } + + /// + // Return true if the specified cookie returned with the response can be set + // or false otherwise. + /// + /*--cef()--*/ + virtual bool CanSetCookie(const CefCookie& cookie) { return true; } + + /// + // Request processing has been canceled. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +#endif // CEF_INCLUDE_CEF_RESOURCE_HANDLER_H_ diff --git a/cefpython/cef3/include/cef_response.h b/cefpython/cef3/include/cef_response.h new file mode 100644 index 00000000..32fbef1b --- /dev/null +++ b/cefpython/cef3/include/cef_response.h @@ -0,0 +1,120 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_RESPONSE_H_ +#define CEF_INCLUDE_CEF_RESPONSE_H_ +#pragma once + +#include "include/cef_base.h" +#include + +/// +// Class used to represent a web response. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library,no_debugct_check)--*/ +class CefResponse : public virtual CefBase { + public: + typedef std::multimap HeaderMap; + + /// + // Create a new CefResponse object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is read-only. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Get the response status code. + /// + /*--cef()--*/ + virtual int GetStatus() =0; + + /// + // Set the response status code. + /// + /*--cef()--*/ + virtual void SetStatus(int status) = 0; + + /// + // Get the response status text. + /// + /*--cef()--*/ + virtual CefString GetStatusText() =0; + + /// + // Set the response status text. + /// + /*--cef()--*/ + virtual void SetStatusText(const CefString& statusText) = 0; + + /// + // Get the response mime type. + /// + /*--cef()--*/ + virtual CefString GetMimeType() = 0; + + /// + // Set the response mime type. + /// + /*--cef()--*/ + virtual void SetMimeType(const CefString& mimeType) = 0; + + /// + // Get the value for the specified response header field. + /// + /*--cef()--*/ + virtual CefString GetHeader(const CefString& name) =0; + + /// + // Get all response header fields. + /// + /*--cef()--*/ + virtual void GetHeaderMap(HeaderMap& headerMap) =0; + + /// + // Set all response header fields. + /// + /*--cef()--*/ + virtual void SetHeaderMap(const HeaderMap& headerMap) =0; +}; + +#endif // CEF_INCLUDE_CEF_RESPONSE_H_ diff --git a/cefpython/cef3/include/cef_runnable.h b/cefpython/cef3/include/cef_runnable.h new file mode 100644 index 00000000..37ad0efe --- /dev/null +++ b/cefpython/cef3/include/cef_runnable.h @@ -0,0 +1,346 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2011 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The contents of this file are a modified extract of base/task.h + +#ifndef CEF_INCLUDE_CEF_RUNNABLE_H_ +#define CEF_INCLUDE_CEF_RUNNABLE_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_task.h" +#ifdef BUILDING_CEF_SHARED +#include "base/tuple.h" +#else +#include "internal/cef_tuple.h" +#endif + +// CefRunnableMethodTraits ----------------------------------------------------- +// +// This traits-class is used by CefRunnableMethod to manage the lifetime of the +// callee object. By default, it is assumed that the callee supports AddRef +// and Release methods. A particular class can specialize this template to +// define other lifetime management. For example, if the callee is known to +// live longer than the CefRunnableMethod object, then a CefRunnableMethodTraits +// struct could be defined with empty RetainCallee and ReleaseCallee methods. +// +// The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way +// for declaring a CefRunnableMethodTraits that disables refcounting. + +template +struct CefRunnableMethodTraits { + CefRunnableMethodTraits() { + } + + ~CefRunnableMethodTraits() { + } + + void RetainCallee(T* obj) { +#ifndef NDEBUG + // Catch NewCefRunnableMethod being called in an object's constructor. + // This isn't safe since the method can be invoked before the constructor + // completes, causing the object to be deleted. + obj->AddRef(); + obj->Release(); +#endif + obj->AddRef(); + } + + void ReleaseCallee(T* obj) { + obj->Release(); + } +}; + +// Convenience macro for declaring a CefRunnableMethodTraits that disables +// refcounting of a class. This is useful if you know that the callee +// will outlive the CefRunnableMethod object and thus do not need the ref +// counts. +// +// The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the +// global namespace scope. Example: +// +// namespace foo { +// class Bar { +// ... +// }; +// } // namespace foo +// +// DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar); +// +// This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the +// class. +#define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \ + template <> \ + struct CefRunnableMethodTraits { \ + void RetainCallee(TypeName* manager) {} \ + void ReleaseCallee(TypeName* manager) {} \ + } + +// CefRunnableMethod and CefRunnableFunction ---------------------------------- +// +// CefRunnable methods are a type of task that call a function on an object +// when they are run. We implement both an object and a set of +// NewCefRunnableMethod and NewCefRunnableFunction functions for convenience. +// These functions are overloaded and will infer the template types, +// simplifying calling code. +// +// The template definitions all use the following names: +// T - the class type of the object you're supplying +// this is not needed for the Static version of the call +// Method/Function - the signature of a pointer to the method or function you +// want to call +// Param - the parameter(s) to the method, possibly packed as a Tuple +// A - the first parameter (if any) to the method +// B - the second parameter (if any) to the method +// +// Put these all together and you get an object that can call a method whose +// signature is: +// R T::MyFunction([A[, B]]) +// +// Usage: +// CefPostTask(TID_UI, NewCefRunnableMethod(object, &Object::method[, a[, b]]) +// CefPostTask(TID_UI, NewCefRunnableFunction(&function[, a[, b]]) + +// CefRunnableMethod and NewCefRunnableMethod implementation ------------------ + +template +class CefRunnableMethod : public CefTask { + public: + CefRunnableMethod(T* obj, Method meth, const Params& params) + : obj_(obj), meth_(meth), params_(params) { + traits_.RetainCallee(obj_); + } + + ~CefRunnableMethod() { + T* obj = obj_; + obj_ = NULL; + if (obj) + traits_.ReleaseCallee(obj); + } + + virtual void Execute() { + if (obj_) + DispatchToMethod(obj_, meth_, params_); + } + + private: + T* obj_; + Method meth_; + Params params_; + CefRunnableMethodTraits traits_; + + IMPLEMENT_REFCOUNTING(CefRunnableMethod); +}; + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method) { + return new CefRunnableMethod(object, method, MakeTuple()); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b, + c)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d) { + return new CefRunnableMethod >(object, method, + MakeTuple(a, b, + c, + d)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, d, + e)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, d, + e, f)); +} + +template +inline CefRefPtr NewCefRunnableMethod(T* object, Method method, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g) { + return new CefRunnableMethod >(object, + method, + MakeTuple(a, b, c, + d, e, f, + g)); +} + +// CefRunnableFunction and NewCefRunnableFunction implementation -------------- + +template +class CefRunnableFunction : public CefTask { + public: + CefRunnableFunction(Function function, const Params& params) + : function_(function), params_(params) { + } + + ~CefRunnableFunction() { + } + + virtual void Execute() { + if (function_) + DispatchToFunction(function_, params_); + } + + private: + Function function_; + Params params_; + + IMPLEMENT_REFCOUNTING(CefRunnableFunction); +}; + +template +inline CefRefPtr NewCefRunnableFunction(Function function) { + return new CefRunnableFunction(function, MakeTuple()); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a) { + return new CefRunnableFunction >(function, MakeTuple(a)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b) { + return new CefRunnableFunction >(function, + MakeTuple(a, b)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, + c)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, + c, + d)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, c, d, e)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f) { + return new CefRunnableFunction >(function, + MakeTuple(a, b, c, d, e, f)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g) { + return new CefRunnableFunction >( + function, MakeTuple(a, b, c, d, e, f, g)); +} + +template +inline CefRefPtr NewCefRunnableFunction(Function function, + const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g, const H& h) { + return new CefRunnableFunction >( + function, MakeTuple(a, b, c, d, e, f, g, h)); +} + +#endif // CEF_INCLUDE_CEF_RUNNABLE_H_ diff --git a/cefpython/cef3/include/cef_scheme.h b/cefpython/cef3/include/cef_scheme.h new file mode 100644 index 00000000..cd8415c0 --- /dev/null +++ b/cefpython/cef3/include/cef_scheme.h @@ -0,0 +1,161 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_SCHEME_H_ +#define CEF_INCLUDE_CEF_SCHEME_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include "include/cef_request.h" +#include "include/cef_response.h" +#include "include/cef_resource_handler.h" + +class CefSchemeHandlerFactory; + + +/// +// Register a scheme handler factory for the specified |scheme_name| and +// optional |domain_name|. An empty |domain_name| value for a standard scheme +// will cause the factory to match all domain names. The |domain_name| value +// will be ignored for non-standard schemes. If |scheme_name| is a built-in +// scheme and no handler is returned by |factory| then the built-in scheme +// handler factory will be called. If |scheme_name| is a custom scheme then +// also implement the CefApp::OnRegisterCustomSchemes() method in all processes. +// This function may be called multiple times to change or remove the factory +// that matches the specified |scheme_name| and optional |domain_name|. +// Returns false if an error occurs. This function may be called on any thread +// in the browser process. +/// +/*--cef(optional_param=domain_name,optional_param=factory)--*/ +bool CefRegisterSchemeHandlerFactory( + const CefString& scheme_name, + const CefString& domain_name, + CefRefPtr factory); + +/// +// Clear all registered scheme handler factories. Returns false on error. This +// function may be called on any thread in the browser process. +/// +/*--cef()--*/ +bool CefClearSchemeHandlerFactories(); + + +/// +// Class that manages custom scheme registrations. +/// +/*--cef(source=library)--*/ +class CefSchemeRegistrar : public virtual CefBase { + public: + /// + // Register a custom scheme. This method should not be called for the built-in + // HTTP, HTTPS, FILE, FTP, ABOUT and DATA schemes. + // + // If |is_standard| is true the scheme will be treated as a standard scheme. + // Standard schemes are subject to URL canonicalization and parsing rules as + // defined in the Common Internet Scheme Syntax RFC 1738 Section 3.1 available + // at http://www.ietf.org/rfc/rfc1738.txt + // + // In particular, the syntax for standard scheme URLs must be of the form: + //
+  //  [scheme]://[username]:[password]@[host]:[port]/[url-path]
+  // 
+ // Standard scheme URLs must have a host component that is a fully qualified + // domain name as defined in Section 3.5 of RFC 1034 [13] and Section 2.1 of + // RFC 1123. These URLs will be canonicalized to "scheme://host/path" in the + // simplest case and "scheme://username:password@host:port/path" in the most + // explicit case. For example, "scheme:host/path" and "scheme:///host/path" + // will both be canonicalized to "scheme://host/path". The origin of a + // standard scheme URL is the combination of scheme, host and port (i.e., + // "scheme://host:port" in the most explicit case). + // + // For non-standard scheme URLs only the "scheme:" component is parsed and + // canonicalized. The remainder of the URL will be passed to the handler + // as-is. For example, "scheme:///some%20text" will remain the same. + // Non-standard scheme URLs cannot be used as a target for form submission. + // + // If |is_local| is true the scheme will be treated as local (i.e., with the + // same security rules as those applied to "file" URLs). Normal pages cannot + // link to or access local URLs. Also, by default, local URLs can only perform + // XMLHttpRequest calls to the same URL (origin + path) that originated the + // request. To allow XMLHttpRequest calls from a local URL to other URLs with + // the same origin set the CefSettings.file_access_from_file_urls_allowed + // value to true. To allow XMLHttpRequest calls from a local URL to all + // origins set the CefSettings.universal_access_from_file_urls_allowed value + // to true. + // + // If |is_display_isolated| is true the scheme will be treated as display- + // isolated. This means that pages cannot display these URLs unless they are + // from the same scheme. For example, pages in another origin cannot create + // iframes or hyperlinks to URLs with this scheme. + // + // This function may be called on any thread. It should only be called once + // per unique |scheme_name| value. If |scheme_name| is already registered or + // if an error occurs this method will return false. + /// + /*--cef()--*/ + virtual bool AddCustomScheme(const CefString& scheme_name, + bool is_standard, + bool is_local, + bool is_display_isolated) =0; +}; + + +/// +// Class that creates CefResourceHandler instances for handling scheme requests. +// The methods of this class will always be called on the IO thread. +/// +/*--cef(source=client)--*/ +class CefSchemeHandlerFactory : public virtual CefBase { + public: + /// + // Return a new resource handler instance to handle the request or an empty + // reference to allow default handling of the request. |browser| and |frame| + // will be the browser window and frame respectively that originated the + // request or NULL if the request did not originate from a browser window + // (for example, if the request came from CefURLRequest). The |request| object + // passed to this method will not contain cookie data. + /// + /*--cef(optional_param=browser,optional_param=frame)--*/ + virtual CefRefPtr Create( + CefRefPtr browser, + CefRefPtr frame, + const CefString& scheme_name, + CefRefPtr request) =0; +}; + +#endif // CEF_INCLUDE_CEF_SCHEME_H_ diff --git a/cefpython/cef3/include/cef_stream.h b/cefpython/cef3/include/cef_stream.h new file mode 100644 index 00000000..6ccec8de --- /dev/null +++ b/cefpython/cef3/include/cef_stream.h @@ -0,0 +1,210 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_STREAM_H_ +#define CEF_INCLUDE_CEF_STREAM_H_ + +#include "include/cef_base.h" + +/// +// Interface the client can implement to provide a custom stream reader. The +// methods of this class may be called on any thread. +/// +/*--cef(source=client)--*/ +class CefReadHandler : public virtual CefBase { + public: + /// + // Read raw binary data. + /// + /*--cef()--*/ + virtual size_t Read(void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Return zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Return non-zero if at end of file. + /// + /*--cef()--*/ + virtual int Eof() =0; +}; + + +/// +// Class used to read data from a stream. The methods of this class may be +// called on any thread. +/// +/*--cef(source=library)--*/ +class CefStreamReader : public virtual CefBase { + public: + /// + // Create a new CefStreamReader object from a file. + /// + /*--cef()--*/ + static CefRefPtr CreateForFile(const CefString& fileName); + /// + // Create a new CefStreamReader object from data. + /// + /*--cef()--*/ + static CefRefPtr CreateForData(void* data, size_t size); + /// + // Create a new CefStreamReader object from a custom handler. + /// + /*--cef()--*/ + static CefRefPtr CreateForHandler( + CefRefPtr handler); + + /// + // Read raw binary data. + /// + /*--cef()--*/ + virtual size_t Read(void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Returns zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Return non-zero if at end of file. + /// + /*--cef()--*/ + virtual int Eof() =0; +}; + + +/// +// Interface the client can implement to provide a custom stream writer. The +// methods of this class may be called on any thread. +/// +/*--cef(source=client)--*/ +class CefWriteHandler : public virtual CefBase { + public: + /// + // Write raw binary data. + /// + /*--cef()--*/ + virtual size_t Write(const void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Return zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Flush the stream. + /// + /*--cef()--*/ + virtual int Flush() =0; +}; + + +/// +// Class used to write data to a stream. The methods of this class may be called +// on any thread. +/// +/*--cef(source=library)--*/ +class CefStreamWriter : public virtual CefBase { + public: + /// + // Create a new CefStreamWriter object for a file. + /// + /*--cef()--*/ + static CefRefPtr CreateForFile(const CefString& fileName); + /// + // Create a new CefStreamWriter object for a custom handler. + /// + /*--cef()--*/ + static CefRefPtr CreateForHandler( + CefRefPtr handler); + + /// + // Write raw binary data. + /// + /*--cef()--*/ + virtual size_t Write(const void* ptr, size_t size, size_t n) =0; + + /// + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. Returns zero on success and non-zero on + // failure. + /// + /*--cef()--*/ + virtual int Seek(int64 offset, int whence) =0; + + /// + // Return the current offset position. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Flush the stream. + /// + /*--cef()--*/ + virtual int Flush() =0; +}; + +#endif // CEF_INCLUDE_CEF_STREAM_H_ diff --git a/cefpython/cef3/include/cef_string_visitor.h b/cefpython/cef3/include/cef_string_visitor.h new file mode 100644 index 00000000..79c9b1cb --- /dev/null +++ b/cefpython/cef3/include/cef_string_visitor.h @@ -0,0 +1,55 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_STRING_VISITOR_H_ +#define CEF_INCLUDE_CEF_STRING_VISITOR_H_ + +#include "include/cef_base.h" + +/// +// Implement this interface to receive string values asynchronously. +/// +/*--cef(source=client)--*/ +class CefStringVisitor : public virtual CefBase { + public: + /// + // Method that will be executed. + /// + /*--cef()--*/ + virtual void Visit(const CefString& string) =0; +}; + +#endif // CEF_INCLUDE_CEF_STRING_VISITOR_H_ diff --git a/cefpython/cef3/include/cef_task.h b/cefpython/cef3/include/cef_task.h new file mode 100644 index 00000000..0ecaa752 --- /dev/null +++ b/cefpython/cef3/include/cef_task.h @@ -0,0 +1,148 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_TASK_H_ +#define CEF_INCLUDE_CEF_TASK_H_ + +#include "include/cef_base.h" + +typedef cef_thread_id_t CefThreadId; + +/// +// Implement this interface for asynchronous task execution. If the task is +// posted successfully and if the associated message loop is still running then +// the Execute() method will be called on the target thread. If the task fails +// to post then the task object may be destroyed on the source thread instead of +// the target thread. For this reason be cautious when performing work in the +// task object destructor. +/// +/*--cef(source=client)--*/ +class CefTask : public virtual CefBase { + public: + /// + // Method that will be executed on the target thread. + /// + /*--cef()--*/ + virtual void Execute() =0; +}; + +/// +// Class that asynchronously executes tasks on the associated thread. It is safe +// to call the methods of this class on any thread. +// +// CEF maintains multiple internal threads that are used for handling different +// types of tasks in different processes. The cef_thread_id_t definitions in +// cef_types.h list the common CEF threads. Task runners are also available for +// other CEF threads as appropriate (for example, V8 WebWorker threads). +/// +/*--cef(source=library)--*/ +class CefTaskRunner : public virtual CefBase { + public: + /// + // Returns the task runner for the current thread. Only CEF threads will have + // task runners. An empty reference will be returned if this method is called + // on an invalid thread. + /// + /*--cef()--*/ + static CefRefPtr GetForCurrentThread(); + + /// + // Returns the task runner for the specified CEF thread. + /// + /*--cef()--*/ + static CefRefPtr GetForThread(CefThreadId threadId); + + /// + // Returns true if this object is pointing to the same task runner as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Returns true if this task runner belongs to the current thread. + /// + /*--cef()--*/ + virtual bool BelongsToCurrentThread() =0; + + /// + // Returns true if this task runner is for the specified CEF thread. + /// + /*--cef()--*/ + virtual bool BelongsToThread(CefThreadId threadId) =0; + + /// + // Post a task for execution on the thread associated with this task runner. + // Execution will occur asynchronously. + /// + /*--cef()--*/ + virtual bool PostTask(CefRefPtr task) =0; + + /// + // Post a task for delayed execution on the thread associated with this task + // runner. Execution will occur asynchronously. Delayed tasks are not + // supported on V8 WebWorker threads and will be executed without the + // specified delay. + /// + /*--cef()--*/ + virtual bool PostDelayedTask(CefRefPtr task, int64 delay_ms) =0; +}; + + +/// +// Returns true if called on the specified thread. Equivalent to using +// CefTaskRunner::GetForThread(threadId)->BelongsToCurrentThread(). +/// +/*--cef()--*/ +bool CefCurrentlyOn(CefThreadId threadId); + +/// +// Post a task for execution on the specified thread. Equivalent to +// using CefTaskRunner::GetForThread(threadId)->PostTask(task). +/// +/*--cef()--*/ +bool CefPostTask(CefThreadId threadId, CefRefPtr task); + +/// +// Post a task for delayed execution on the specified thread. Equivalent to +// using CefTaskRunner::GetForThread(threadId)->PostDelayedTask(task, delay_ms). +/// +/*--cef()--*/ +bool CefPostDelayedTask(CefThreadId threadId, CefRefPtr task, + int64 delay_ms); + + +#endif // CEF_INCLUDE_CEF_TASK_H_ diff --git a/cefpython/cef3/include/cef_trace.h b/cefpython/cef3/include/cef_trace.h new file mode 100644 index 00000000..a2cf2966 --- /dev/null +++ b/cefpython/cef3/include/cef_trace.h @@ -0,0 +1,132 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. Portons copyright (c) 2012 +// Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +// See cef_trace_event.h for trace macros and additonal documentation. + +#ifndef CEF_INCLUDE_CEF_TRACE_H_ +#define CEF_INCLUDE_CEF_TRACE_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Implement this interface to receive trace notifications. The methods of this +// class will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefTraceClient : public virtual CefBase { + public: + /// + // Called 0 or more times between CefBeginTracing and OnEndTracingComplete + // with a UTF8 JSON |fragment| of the specified |fragment_size|. Do not keep + // a reference to |fragment|. + /// + /*--cef()--*/ + virtual void OnTraceDataCollected(const char* fragment, + size_t fragment_size) {} + + /// + // Called in response to CefGetTraceBufferPercentFullAsync. + /// + /*--cef()--*/ + virtual void OnTraceBufferPercentFullReply(float percent_full) {} + + /// + // Called after all processes have sent their trace data. + /// + /*--cef()--*/ + virtual void OnEndTracingComplete() {} +}; + + +/// +// Start tracing events on all processes. Tracing begins immediately locally, +// and asynchronously on child processes as soon as they receive the +// BeginTracing request. +// +// If CefBeginTracing was called previously, or if a CefEndTracingAsync call is +// pending, CefBeginTracing will fail and return false. +// +// |categories| is a comma-delimited list of category wildcards. A category can +// have an optional '-' prefix to make it an excluded category. Having both +// included and excluded categories in the same list is not supported. +// +// Example: "test_MyTest*" +// Example: "test_MyTest*,test_OtherStuff" +// Example: "-excluded_category1,-excluded_category2" +// +// This function must be called on the browser process UI thread. +/// +/*--cef(optional_param=client,optional_param=categories)--*/ +bool CefBeginTracing(CefRefPtr client, + const CefString& categories); + +/// +// Get the maximum trace buffer percent full state across all processes. +// +// CefTraceClient::OnTraceBufferPercentFullReply will be called asynchronously +// after the value is determined. When any child process reaches 100% full +// tracing will end automatically and CefTraceClient::OnEndTracingComplete +// will be called. This function fails and returns false if trace is ending or +// disabled, no CefTraceClient was passed to CefBeginTracing, or if a previous +// call to CefGetTraceBufferPercentFullAsync is pending. +// +// This function must be called on the browser process UI thread. +/// +/*--cef()--*/ +bool CefGetTraceBufferPercentFullAsync(); + +/// +// Stop tracing events on all processes. +// +// This function will fail and return false if a previous call to +// CefEndTracingAsync is already pending or if CefBeginTracing was not called. +// +// This function must be called on the browser process UI thread. +/// +/*--cef()--*/ +bool CefEndTracingAsync(); + +/// +// Returns the current system trace time or, if none is defined, the current +// high-res time. Can be used by clients to synchronize with the time +// information in trace events. +/// +/*--cef()--*/ +int64 CefNowFromSystemTraceTime(); + +#endif // CEF_INCLUDE_CEF_TRACE_H_ diff --git a/cefpython/cef3/include/cef_trace_event.h b/cefpython/cef3/include/cef_trace_event.h new file mode 100644 index 00000000..54162b23 --- /dev/null +++ b/cefpython/cef3/include/cef_trace_event.h @@ -0,0 +1,471 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. Portions copyright (c) 2012 +// Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/// +// Trace events are for tracking application performance and resource usage. +// Macros are provided to track: +// Begin and end of function calls +// Counters +// +// Events are issued against categories. Whereas LOG's categories are statically +// defined, TRACE categories are created implicitly with a string. For example: +// CEF_TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") +// +// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope: +// CEF_TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") +// doSomethingCostly() +// CEF_TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") +// Note: Our tools can't always determine the correct BEGIN/END pairs unless +// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you +// need them to be in separate scopes. +// +// A common use case is to trace entire function scopes. This issues a trace +// BEGIN and END automatically: +// void doSomethingCostly() { +// CEF_TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); +// ... +// } +// +// Additional parameters can be associated with an event: +// void doSomethingCostly2(int howMuch) { +// CEF_TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", +// "howMuch", howMuch); +// ... +// } +// +// The trace system will automatically add to this information the current +// process id, thread id, and a timestamp in microseconds. +// +// To trace an asynchronous procedure such as an IPC send/receive, use +// ASYNC_BEGIN and ASYNC_END: +// [single threaded sender code] +// static int send_count = 0; +// ++send_count; +// CEF_TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count); +// Send(new MyMessage(send_count)); +// [receive code] +// void OnMyMessage(send_count) { +// CEF_TRACE_EVENT_ASYNC_END0("ipc", "message", send_count); +// } +// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs. +// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. +// Pointers can be used for the ID parameter, and they will be mangled +// internally so that the same pointer on two different processes will not +// match. For example: +// class MyTracedClass { +// public: +// MyTracedClass() { +// CEF_TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this); +// } +// ~MyTracedClass() { +// CEF_TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this); +// } +// } +// +// The trace event also supports counters, which is a way to track a quantity +// as it varies over time. Counters are created with the following macro: +// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue); +// +// Counters are process-specific. The macro itself can be issued from any +// thread, however. +// +// Sometimes, you want to track two counters at once. You can do this with two +// counter macros: +// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]); +// CEF_TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]); +// Or you can do it with a combined macro: +// CEF_TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter", +// "bytesPinned", g_myCounterValue[0], +// "bytesAllocated", g_myCounterValue[1]); +// This indicates to the tracing UI that these counters should be displayed +// in a single graph, as a summed area chart. +// +// Since counters are in a global namespace, you may want to disembiguate with a +// unique ID, by using the CEF_TRACE_COUNTER_ID* variations. +// +// By default, trace collection is compiled in, but turned off at runtime. +// Collecting trace data is the responsibility of the embedding application. In +// CEF's case, calling BeginTracing will turn on tracing on all active +// processes. +// +// +// Memory scoping note: +// Tracing copies the pointers, not the string content, of the strings passed +// in for category, name, and arg_names. Thus, the following code will cause +// problems: +// char* str = strdup("impprtantName"); +// CEF_TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! +// free(str); // Trace system now has dangling pointer +// +// To avoid this issue with the |name| and |arg_name| parameters, use the +// CEF_TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime +// overhead. +// Notes: The category must always be in a long-lived char* (i.e. static const). +// The |arg_values|, when used, are always deep copied with the _COPY +// macros. +// +// +// Thread Safety: +// All macros are thread safe and can be used from any process. +/// + +#ifndef CEF_INCLUDE_CEF_TRACE_EVENT_H_ +#define CEF_INCLUDE_CEF_TRACE_EVENT_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions for tracing counters and functions; called from macros. +// - |category| string must have application lifetime (static or literal). They +// may not include "(quotes) chars. +// - |argX_name|, |argX_val|, |valueX_name|, |valeX_val| are optional parameters +// and represent pairs of name and values of arguments +// - |copy| is used to avoid memory scoping issues with the |name| and +// |arg_name| parameters by copying them +// - |id| is used to disambiguate counters with the same name, or match async +// trace events + +CEF_EXPORT void cef_trace_event_instant(const char* category, + const char* name, + const char* arg1_name, + uint64 arg1_val, + const char* arg2_name, + uint64 arg2_val, + int copy); +CEF_EXPORT void cef_trace_event_begin(const char* category, + const char* name, + const char* arg1_name, + uint64 arg1_val, + const char* arg2_name, + uint64 arg2_val, + int copy); +CEF_EXPORT void cef_trace_event_end(const char* category, + const char* name, + const char* arg1_name, + uint64 arg1_val, + const char* arg2_name, + uint64 arg2_val, + int copy); +CEF_EXPORT void cef_trace_counter(const char* category, + const char* name, + const char* value1_name, + uint64 value1_val, + const char* value2_name, + uint64 value2_val, + int copy); +CEF_EXPORT void cef_trace_counter_id(const char* category, + const char* name, + uint64 id, + const char* value1_name, + uint64 value1_val, + const char* value2_name, + uint64 value2_val, + int copy); +CEF_EXPORT void cef_trace_event_async_begin(const char* category, + const char* name, + uint64 id, + const char* arg1_name, + uint64 arg1_val, + const char* arg2_name, + uint64 arg2_val, + int copy); +CEF_EXPORT void cef_trace_event_async_step(const char* category, + const char* name, + uint64 id, + uint64 step, + const char* arg1_name, + uint64 arg1_val, + int copy); +CEF_EXPORT void cef_trace_event_async_end(const char* category, + const char* name, + uint64 id, + const char* arg1_name, + uint64 arg1_val, + const char* arg2_name, + uint64 arg2_val, + int copy); + +#ifdef __cplusplus +} +#endif + +// Records a pair of begin and end events called "name" for the current +// scope, with 0, 1 or 2 associated arguments. If the category is not +// enabled, then this does nothing. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_EVENT0(category, name) \ + cef_trace_event_begin(category, name, NULL, 0, NULL, 0, false); \ + CEF_INTERNAL_TRACE_END_ON_SCOPE_CLOSE(category, name) +#define CEF_TRACE_EVENT1(category, name, arg1_name, arg1_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, NULL, 0, false); \ + CEF_INTERNAL_TRACE_END_ON_SCOPE_CLOSE(category, name) +#define CEF_TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val, false); \ + CEF_INTERNAL_TRACE_END_ON_SCOPE_CLOSE(category, name) + +// Implementation detail: trace event macros create temporary variable names. +// These macros give each temporary variable a unique name based on the line +// number to prevent name collisions. +#define CEF_INTERNAL_TRACE_EVENT_UID3(a,b) \ + cef_trace_event_unique_##a##b +#define CEF_INTERNAL_TRACE_EVENT_UID2(a,b) \ + CEF_INTERNAL_TRACE_EVENT_UID3(a,b) +#define CEF_INTERNAL_TRACE_EVENT_UID(name_prefix) \ + CEF_INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) + +// Implementation detail: internal macro to end end event when the scope ends. +#define CEF_INTERNAL_TRACE_END_ON_SCOPE_CLOSE(category, name) \ + cef_trace_event_internal::CefTraceEndOnScopeClose \ + CEF_INTERNAL_TRACE_EVENT_UID(profileScope)(category, name) + +// Records a single event called "name" immediately, with 0, 1 or 2 +// associated arguments. If the category is not enabled, then this +// does nothing. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_EVENT_INSTANT0(category, name) \ + cef_trace_event_instant(category, name, NULL, 0, NULL, 0, false) +#define CEF_TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ + cef_trace_event_instant(category, name, arg1_name, arg1_val, NULL, 0, false) +#define CEF_TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_instant(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, false) +#define CEF_TRACE_EVENT_COPY_INSTANT0(category, name) \ + cef_trace_event_instant(category, name, NULL, 0, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ + cef_trace_event_instant(category, name, arg1_name, arg1_val, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_instant(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, true) + +// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 +// associated arguments. If the category is not enabled, then this +// does nothing. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_EVENT_BEGIN0(category, name) \ + cef_trace_event_begin(category, name, NULL, 0, NULL, 0, false) +#define CEF_TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, NULL, 0, false) +#define CEF_TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, false) +#define CEF_TRACE_EVENT_COPY_BEGIN0(category, name) \ + cef_trace_event_begin(category, name, NULL, 0, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_begin(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, true) + +// Records a single END event for "name" immediately. If the category +// is not enabled, then this does nothing. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_EVENT_END0(category, name) \ + cef_trace_event_end(category, name, NULL, 0, NULL, 0, false) +#define CEF_TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ + cef_trace_event_end(category, name, arg1_name, arg1_val, NULL, 0, false) +#define CEF_TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_end(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, false) +#define CEF_TRACE_EVENT_COPY_END0(category, name) \ + cef_trace_event_end(category, name, NULL, 0, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ + cef_trace_event_end(category, name, arg1_name, arg1_val, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_end(category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val, true) + +// Records the value of a counter called "name" immediately. Value +// must be representable as a 32 bit integer. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_COUNTER1(category, name, value) \ + cef_trace_counter(category, name, NULL, value, NULL, 0, false) +#define CEF_TRACE_COPY_COUNTER1(category, name, value) \ + cef_trace_counter(category, name, NULL, value, NULL, 0, true) + +// Records the values of a multi-parted counter called "name" immediately. +// The UI will treat value1 and value2 as parts of a whole, displaying their +// values as a stacked-bar chart. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +#define CEF_TRACE_COUNTER2(category, name, value1_name, value1_val, \ + value2_name, value2_val) \ + cef_trace_counter(category, name, value1_name, value1_val, value2_name, \ + value2_val, false) +#define CEF_TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ + value2_name, value2_val) \ + cef_trace_counter(category, name, value1_name, value1_val, value2_name, \ + value2_val, true) + +// Records the value of a counter called "name" immediately. Value +// must be representable as a 32 bit integer. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +// - |id| is used to disambiguate counters with the same name. It must either +// be a pointer or an integer value up to 64 bits. If it's a pointer, the +// bits will be xored with a hash of the process ID so that the same pointer +// on two different processes will not collide. +#define CEF_TRACE_COUNTER_ID1(category, name, id, value) \ + cef_trace_counter_id(category, name, id, NULL, value, NULL, 0, false) +#define CEF_TRACE_COPY_COUNTER_ID1(category, name, id, value) \ + cef_trace_counter_id(category, name, id, NULL, value, NULL, 0, true) + +// Records the values of a multi-parted counter called "name" immediately. +// The UI will treat value1 and value2 as parts of a whole, displaying their +// values as a stacked-bar chart. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +// - |id| is used to disambiguate counters with the same name. It must either +// be a pointer or an integer value up to 64 bits. If it's a pointer, the +// bits will be xored with a hash of the process ID so that the same pointer +// on two different processes will not collide. +#define CEF_TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ + value2_name, value2_val) \ + cef_trace_counter_id(category, name, id, value1_name, value1_val, \ + value2_name, value2_val, false) +#define CEF_TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, \ + value1_val, value2_name, value2_val) \ + cef_trace_counter_id(category, name, id, value1_name, value1_val, \ + value2_name, value2_val, true) + + +// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2 +// associated arguments. If the category is not enabled, then this +// does nothing. +// - category and name strings must have application lifetime (statics or +// literals). They may not include " chars. +// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. +// ASYNC events are considered to match if their category, name and id values +// all match. |id| must either be a pointer or an integer value up to 64 +// bits. If it's a pointer, the bits will be xored with a hash of the process +// ID sothat the same pointer on two different processes will not collide. +// An asynchronous operation can consist of multiple phases. The first phase is +// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the +// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END. +// An async operation can span threads and processes, but all events in that +// operation must use the same |name| and |id|. Each event can have its own +// args. +#define CEF_TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ + cef_trace_event_async_begin(category, name, id, NULL, 0, NULL, 0, false) +#define CEF_TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ + cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, NULL, \ + 0, false) +#define CEF_TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val, false) +#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ + cef_trace_event_async_begin(category, name, id, NULL, 0, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, \ + arg1_val) \ + cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, NULL, \ + 0, true) +#define CEF_TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ + cef_trace_event_async_begin(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val, true) + +// Records a single ASYNC_STEP event for |step| immediately. If the category +// is not enabled, then this does nothing. The |name| and |id| must match the +// ASYNC_BEGIN event above. The |step| param identifies this step within the +// async event. This should be called at the beginning of the next phase of an +// asynchronous operation. +#define CEF_TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ + cef_trace_event_async_step(category, name, id, step, NULL, 0, false) +#define CEF_TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ + arg1_name, arg1_val) \ + cef_trace_event_async_step(category, name, id, step, arg1_name, arg1_val, \ + false) +#define CEF_TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ + cef_trace_event_async_step(category, name, id, step, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ + arg1_name, arg1_val) \ + cef_trace_event_async_step(category, name, id, step, arg1_name, arg1_val, \ + true) + +// Records a single ASYNC_END event for "name" immediately. If the category +// is not enabled, then this does nothing. +#define CEF_TRACE_EVENT_ASYNC_END0(category, name, id) \ + cef_trace_event_async_end(category, name, id, NULL, 0, NULL, 0, false) +#define CEF_TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ + cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, NULL, 0, \ + false) +#define CEF_TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val) \ + cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val, false) +#define CEF_TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ + cef_trace_event_async_end(category, name, id, NULL, 0, NULL, 0, true) +#define CEF_TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, \ + arg1_val) \ + cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, NULL, 0, \ + true) +#define CEF_TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ + cef_trace_event_async_end(category, name, id, arg1_name, arg1_val, \ + arg2_name, arg2_val, true) + +namespace cef_trace_event_internal { + +// Used by CEF_TRACE_EVENTx macro. Do not use directly. +class CefTraceEndOnScopeClose { + public: + CefTraceEndOnScopeClose(const char* category, const char* name) + : category_(category), name_(name) { + } + ~CefTraceEndOnScopeClose() { + cef_trace_event_end(category_, name_, NULL, 0, NULL, 0, false); + } + + private: + const char* category_; + const char* name_; +}; + +} // cef_trace_event_internal + +#endif // CEF_INCLUDE_CEF_TRACE_EVENT_H_ diff --git a/cefpython/cef3/include/cef_url.h b/cefpython/cef3/include/cef_url.h new file mode 100644 index 00000000..c5cb21aa --- /dev/null +++ b/cefpython/cef3/include/cef_url.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_URL_H_ +#define CEF_INCLUDE_CEF_URL_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Parse the specified |url| into its component parts. +// Returns false if the URL is empty or invalid. +/// +/*--cef()--*/ +bool CefParseURL(const CefString& url, + CefURLParts& parts); + +/// +// Creates a URL from the specified |parts|, which must contain a non-empty +// spec or a non-empty host and path (at a minimum), but not both. +// Returns false if |parts| isn't initialized as described. +/// +/*--cef()--*/ +bool CefCreateURL(const CefURLParts& parts, + CefString& url); + +#endif // CEF_INCLUDE_CEF_URL_H_ diff --git a/cefpython/cef3/include/cef_urlrequest.h b/cefpython/cef3/include/cef_urlrequest.h new file mode 100644 index 00000000..02a9da68 --- /dev/null +++ b/cefpython/cef3/include/cef_urlrequest.h @@ -0,0 +1,183 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_URLREQUEST_H_ +#define CEF_INCLUDE_CEF_URLREQUEST_H_ +#pragma once + +#include "include/cef_auth_callback.h" +#include "include/cef_base.h" +#include "include/cef_request.h" +#include "include/cef_response.h" + +class CefURLRequestClient; + +/// +// Class used to make a URL request. URL requests are not associated with a +// browser instance so no CefClient callbacks will be executed. URL requests +// can be created on any valid CEF thread in either the browser or render +// process. Once created the methods of the URL request object must be accessed +// on the same thread that created it. +/// +/*--cef(source=library)--*/ +class CefURLRequest : public virtual CefBase { + public: + typedef cef_urlrequest_status_t Status; + typedef cef_errorcode_t ErrorCode; + + /// + // Create a new URL request. Only GET, POST, HEAD, DELETE and PUT request + // methods are supported. Multiple post data elements are not supported and + // elements of type PDE_TYPE_FILE are only supported for requests originating + // from the browser process. Requests originating from the render process will + // receive the same handling as requests originating from Web content -- if + // the response contains Content-Disposition or Mime-Type header values that + // would not normally be rendered then the response may receive special + // handling inside the browser (for example, via the file download code path + // instead of the URL request code path). The |request| object will be marked + // as read-only after calling this method. + /// + /*--cef()--*/ + static CefRefPtr Create( + CefRefPtr request, + CefRefPtr client); + + /// + // Returns the request object used to create this URL request. The returned + // object is read-only and should not be modified. + /// + /*--cef()--*/ + virtual CefRefPtr GetRequest() =0; + + /// + // Returns the client. + /// + /*--cef()--*/ + virtual CefRefPtr GetClient() =0; + + /// + // Returns the request status. + /// + /*--cef(default_retval=UR_UNKNOWN)--*/ + virtual Status GetRequestStatus() =0; + + /// + // Returns the request error if status is UR_CANCELED or UR_FAILED, or 0 + // otherwise. + /// + /*--cef(default_retval=ERR_NONE)--*/ + virtual ErrorCode GetRequestError() =0; + + /// + // Returns the response, or NULL if no response information is available. + // Response information will only be available after the upload has completed. + // The returned object is read-only and should not be modified. + /// + /*--cef()--*/ + virtual CefRefPtr GetResponse() =0; + + /// + // Cancel the request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +/// +// Interface that should be implemented by the CefURLRequest client. The +// methods of this class will be called on the same thread that created the +// request unless otherwise documented. +/// +/*--cef(source=client)--*/ +class CefURLRequestClient : public virtual CefBase { + public: + /// + // Notifies the client that the request has completed. Use the + // CefURLRequest::GetRequestStatus method to determine if the request was + // successful or not. + /// + /*--cef()--*/ + virtual void OnRequestComplete(CefRefPtr request) =0; + + /// + // Notifies the client of upload progress. |current| denotes the number of + // bytes sent so far and |total| is the total size of uploading data (or -1 if + // chunked upload is enabled). This method will only be called if the + // UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request. + /// + /*--cef()--*/ + virtual void OnUploadProgress(CefRefPtr request, + uint64 current, + uint64 total) =0; + + /// + // Notifies the client of download progress. |current| denotes the number of + // bytes received up to the call and |total| is the expected total size of the + // response (or -1 if not determined). + /// + /*--cef()--*/ + virtual void OnDownloadProgress(CefRefPtr request, + uint64 current, + uint64 total) =0; + + /// + // Called when some part of the response is read. |data| contains the current + // bytes received since the last call. This method will not be called if the + // UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request. + /// + /*--cef()--*/ + virtual void OnDownloadData(CefRefPtr request, + const void* data, + size_t data_length) =0; + + /// + // Called on the IO thread when the browser needs credentials from the user. + // |isProxy| indicates whether the host is a proxy server. |host| contains the + // hostname and |port| contains the port number. Return true to continue the + // request and call CefAuthCallback::Continue() when the authentication + // information is available. Return false to cancel the request. This method + // will only be called for requests initiated from the browser process. + /// + /*--cef(optional_param=realm)--*/ + virtual bool GetAuthCredentials(bool isProxy, + const CefString& host, + int port, + const CefString& realm, + const CefString& scheme, + CefRefPtr callback) =0; +}; + +#endif // CEF_INCLUDE_CEF_URLREQUEST_H_ diff --git a/cefpython/cef3/include/cef_v8.h b/cefpython/cef3/include/cef_v8.h new file mode 100644 index 00000000..3f05b802 --- /dev/null +++ b/cefpython/cef3/include/cef_v8.h @@ -0,0 +1,879 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + + +#ifndef CEF_INCLUDE_CEF_V8_H_ +#define CEF_INCLUDE_CEF_V8_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" +#include "include/cef_frame.h" +#include "include/cef_task.h" +#include + +class CefV8Exception; +class CefV8Handler; +class CefV8StackFrame; +class CefV8Value; + + +/// +// Register a new V8 extension with the specified JavaScript extension code and +// handler. Functions implemented by the handler are prototyped using the +// keyword 'native'. The calling of a native function is restricted to the scope +// in which the prototype of the native function is defined. This function may +// only be called on the render process main thread. +// +// Example JavaScript extension code: +//
+//   // create the 'example' global object if it doesn't already exist.
+//   if (!example)
+//     example = {};
+//   // create the 'example.test' global object if it doesn't already exist.
+//   if (!example.test)
+//     example.test = {};
+//   (function() {
+//     // Define the function 'example.test.myfunction'.
+//     example.test.myfunction = function() {
+//       // Call CefV8Handler::Execute() with the function name 'MyFunction'
+//       // and no arguments.
+//       native function MyFunction();
+//       return MyFunction();
+//     };
+//     // Define the getter function for parameter 'example.test.myparam'.
+//     example.test.__defineGetter__('myparam', function() {
+//       // Call CefV8Handler::Execute() with the function name 'GetMyParam'
+//       // and no arguments.
+//       native function GetMyParam();
+//       return GetMyParam();
+//     });
+//     // Define the setter function for parameter 'example.test.myparam'.
+//     example.test.__defineSetter__('myparam', function(b) {
+//       // Call CefV8Handler::Execute() with the function name 'SetMyParam'
+//       // and a single argument.
+//       native function SetMyParam();
+//       if(b) SetMyParam(b);
+//     });
+//
+//     // Extension definitions can also contain normal JavaScript variables
+//     // and functions.
+//     var myint = 0;
+//     example.test.increment = function() {
+//       myint += 1;
+//       return myint;
+//     };
+//   })();
+// 
+// Example usage in the page: +//
+//   // Call the function.
+//   example.test.myfunction();
+//   // Set the parameter.
+//   example.test.myparam = value;
+//   // Get the parameter.
+//   value = example.test.myparam;
+//   // Call another function.
+//   example.test.increment();
+// 
+/// +/*--cef(optional_param=handler)--*/ +bool CefRegisterExtension(const CefString& extension_name, + const CefString& javascript_code, + CefRefPtr handler); + + +/// +// Class representing a V8 context handle. V8 handles can only be accessed from +// the thread on which they are created. Valid threads for creating a V8 handle +// include the render process main thread (TID_RENDERER) and WebWorker threads. +// A task runner for posting tasks on the associated thread can be retrieved via +// the CefV8Context::GetTaskRunner() method. +/// +/*--cef(source=library)--*/ +class CefV8Context : public virtual CefBase { + public: + /// + // Returns the current (top) context object in the V8 context stack. + /// + /*--cef()--*/ + static CefRefPtr GetCurrentContext(); + + /// + // Returns the entered (bottom) context object in the V8 context stack. + /// + /*--cef()--*/ + static CefRefPtr GetEnteredContext(); + + /// + // Returns true if V8 is currently inside a context. + /// + /*--cef()--*/ + static bool InContext(); + + /// + // Returns the task runner associated with this context. V8 handles can only + // be accessed from the thread on which they are created. This method can be + // called on any render process thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetTaskRunner() =0; + + /// + // Returns true if the underlying handle is valid and it can be accessed on + // the current thread. Do not call any other methods if this method returns + // false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the browser for this context. This method will return an empty + // reference for WebWorker contexts. + /// + /*--cef()--*/ + virtual CefRefPtr GetBrowser() =0; + + /// + // Returns the frame for this context. This method will return an empty + // reference for WebWorker contexts. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame() =0; + + /// + // Returns the global object for this context. The context must be entered + // before calling this method. + /// + /*--cef()--*/ + virtual CefRefPtr GetGlobal() =0; + + /// + // Enter this context. A context must be explicitly entered before creating a + // V8 Object, Array, Function or Date asynchronously. Exit() must be called + // the same number of times as Enter() before releasing this context. V8 + // objects belong to the context in which they are created. Returns true if + // the scope was entered successfully. + /// + /*--cef()--*/ + virtual bool Enter() =0; + + /// + // Exit this context. Call this method only after calling Enter(). Returns + // true if the scope was exited successfully. + /// + /*--cef()--*/ + virtual bool Exit() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Evaluates the specified JavaScript code using this context's global object. + // On success |retval| will be set to the return value, if any, and the + // function will return true. On failure |exception| will be set to the + // exception, if any, and the function will return false. + /// + /*--cef()--*/ + virtual bool Eval(const CefString& code, + CefRefPtr& retval, + CefRefPtr& exception) =0; +}; + + +typedef std::vector > CefV8ValueList; + +/// +// Interface that should be implemented to handle V8 function calls. The methods +// of this class will be called on the thread associated with the V8 function. +/// +/*--cef(source=client)--*/ +class CefV8Handler : public virtual CefBase { + public: + /// + // Handle execution of the function identified by |name|. |object| is the + // receiver ('this' object) of the function. |arguments| is the list of + // arguments passed to the function. If execution succeeds set |retval| to the + // function return value. If execution fails set |exception| to the exception + // that will be thrown. Return true if execution was handled. + /// + /*--cef()--*/ + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) =0; +}; + +/// +// Interface that should be implemented to handle V8 accessor calls. Accessor +// identifiers are registered by calling CefV8Value::SetValue(). The methods +// of this class will be called on the thread associated with the V8 accessor. +/// +/*--cef(source=client)--*/ +class CefV8Accessor : public virtual CefBase { + public: + /// + // Handle retrieval the accessor value identified by |name|. |object| is the + // receiver ('this' object) of the accessor. If retrieval succeeds set + // |retval| to the return value. If retrieval fails set |exception| to the + // exception that will be thrown. Return true if accessor retrieval was + // handled. + /// + /*--cef()--*/ + virtual bool Get(const CefString& name, + const CefRefPtr object, + CefRefPtr& retval, + CefString& exception) =0; + + /// + // Handle assignment of the accessor value identified by |name|. |object| is + // the receiver ('this' object) of the accessor. |value| is the new value + // being assigned to the accessor. If assignment fails set |exception| to the + // exception that will be thrown. Return true if accessor assignment was + // handled. + /// + /*--cef()--*/ + virtual bool Set(const CefString& name, + const CefRefPtr object, + const CefRefPtr value, + CefString& exception) =0; +}; + +/// +// Class representing a V8 exception. The methods of this class may be called on +// any render process thread. +/// +/*--cef(source=library)--*/ +class CefV8Exception : public virtual CefBase { + public: + /// + // Returns the exception message. + /// + /*--cef()--*/ + virtual CefString GetMessage() =0; + + /// + // Returns the line of source code that the exception occurred within. + /// + /*--cef()--*/ + virtual CefString GetSourceLine() =0; + + /// + // Returns the resource name for the script from where the function causing + // the error originates. + /// + /*--cef()--*/ + virtual CefString GetScriptResourceName() =0; + + /// + // Returns the 1-based number of the line where the error occurred or 0 if the + // line number is unknown. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + /// + // Returns the index within the script of the first character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetStartPosition() =0; + + /// + // Returns the index within the script of the last character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetEndPosition() =0; + + /// + // Returns the index within the line of the first character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetStartColumn() =0; + + /// + // Returns the index within the line of the last character where the error + // occurred. + /// + /*--cef()--*/ + virtual int GetEndColumn() =0; +}; + +/// +// Class representing a V8 value handle. V8 handles can only be accessed from +// the thread on which they are created. Valid threads for creating a V8 handle +// include the render process main thread (TID_RENDERER) and WebWorker threads. +// A task runner for posting tasks on the associated thread can be retrieved via +// the CefV8Context::GetTaskRunner() method. +/// +/*--cef(source=library)--*/ +class CefV8Value : public virtual CefBase { + public: + typedef cef_v8_accesscontrol_t AccessControl; + typedef cef_v8_propertyattribute_t PropertyAttribute; + + /// + // Create a new CefV8Value object of type undefined. + /// + /*--cef()--*/ + static CefRefPtr CreateUndefined(); + + /// + // Create a new CefV8Value object of type null. + /// + /*--cef()--*/ + static CefRefPtr CreateNull(); + + /// + // Create a new CefV8Value object of type bool. + /// + /*--cef()--*/ + static CefRefPtr CreateBool(bool value); + + /// + // Create a new CefV8Value object of type int. + /// + /*--cef()--*/ + static CefRefPtr CreateInt(int32 value); + + /// + // Create a new CefV8Value object of type unsigned int. + /// + /*--cef()--*/ + static CefRefPtr CreateUInt(uint32 value); + + /// + // Create a new CefV8Value object of type double. + /// + /*--cef()--*/ + static CefRefPtr CreateDouble(double value); + + /// + // Create a new CefV8Value object of type Date. This method should only be + // called from within the scope of a CefV8ContextHandler, CefV8Handler or + // CefV8Accessor callback, or in combination with calling Enter() and Exit() + // on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateDate(const CefTime& date); + + /// + // Create a new CefV8Value object of type string. + /// + /*--cef(optional_param=value)--*/ + static CefRefPtr CreateString(const CefString& value); + + /// + // Create a new CefV8Value object of type object with optional accessor. This + // method should only be called from within the scope of a + // CefV8ContextHandler, CefV8Handler or CefV8Accessor callback, or in + // combination with calling Enter() and Exit() on a stored CefV8Context + // reference. + /// + /*--cef(optional_param=accessor)--*/ + static CefRefPtr CreateObject(CefRefPtr accessor); + + /// + // Create a new CefV8Value object of type array with the specified |length|. + // If |length| is negative the returned array will have length 0. This method + // should only be called from within the scope of a CefV8ContextHandler, + // CefV8Handler or CefV8Accessor callback, or in combination with calling + // Enter() and Exit() on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateArray(int length); + + /// + // Create a new CefV8Value object of type function. This method should only be + // called from within the scope of a CefV8ContextHandler, CefV8Handler or + // CefV8Accessor callback, or in combination with calling Enter() and Exit() + // on a stored CefV8Context reference. + /// + /*--cef()--*/ + static CefRefPtr CreateFunction(const CefString& name, + CefRefPtr handler); + + /// + // Returns true if the underlying handle is valid and it can be accessed on + // the current thread. Do not call any other methods if this method returns + // false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // True if the value type is undefined. + /// + /*--cef()--*/ + virtual bool IsUndefined() =0; + + /// + // True if the value type is null. + /// + /*--cef()--*/ + virtual bool IsNull() =0; + + /// + // True if the value type is bool. + /// + /*--cef()--*/ + virtual bool IsBool() =0; + + /// + // True if the value type is int. + /// + /*--cef()--*/ + virtual bool IsInt() =0; + + /// + // True if the value type is unsigned int. + /// + /*--cef()--*/ + virtual bool IsUInt() =0; + + /// + // True if the value type is double. + /// + /*--cef()--*/ + virtual bool IsDouble() =0; + + /// + // True if the value type is Date. + /// + /*--cef()--*/ + virtual bool IsDate() =0; + + /// + // True if the value type is string. + /// + /*--cef()--*/ + virtual bool IsString() =0; + + /// + // True if the value type is object. + /// + /*--cef()--*/ + virtual bool IsObject() =0; + + /// + // True if the value type is array. + /// + /*--cef()--*/ + virtual bool IsArray() =0; + + /// + // True if the value type is function. + /// + /*--cef()--*/ + virtual bool IsFunction() =0; + + /// + // Returns true if this object is pointing to the same handle as |that| + // object. + /// + /*--cef()--*/ + virtual bool IsSame(CefRefPtr that) =0; + + /// + // Return a bool value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual bool GetBoolValue() =0; + + /// + // Return an int value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual int32 GetIntValue() =0; + + /// + // Return an unisgned int value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual uint32 GetUIntValue() =0; + + /// + // Return a double value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual double GetDoubleValue() =0; + + /// + // Return a Date value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual CefTime GetDateValue() =0; + + /// + // Return a string value. The underlying data will be converted to if + // necessary. + /// + /*--cef()--*/ + virtual CefString GetStringValue() =0; + + + // OBJECT METHODS - These methods are only available on objects. Arrays and + // functions are also objects. String- and integer-based keys can be used + // interchangably with the framework converting between them as necessary. + + /// + // Returns true if this is a user created object. + /// + /*--cef()--*/ + virtual bool IsUserCreated() =0; + + /// + // Returns true if the last method call resulted in an exception. This + // attribute exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool HasException() =0; + + /// + // Returns the exception resulting from the last method call. This attribute + // exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual CefRefPtr GetException() =0; + + /// + // Clears the last exception and returns true on success. + /// + /*--cef()--*/ + virtual bool ClearException() =0; + + /// + // Returns true if this object will re-throw future exceptions. This attribute + // exists only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool WillRethrowExceptions() =0; + + /// + // Set whether this object will re-throw future exceptions. By default + // exceptions are not re-thrown. If a exception is re-thrown the current + // context should not be accessed again until after the exception has been + // caught and not re-thrown. Returns true on success. This attribute exists + // only in the scope of the current CEF value object. + /// + /*--cef()--*/ + virtual bool SetRethrowExceptions(bool rethrow) =0; + + /// + // Returns true if the object has a value with the specified identifier. + /// + /*--cef(capi_name=has_value_bykey,optional_param=key)--*/ + virtual bool HasValue(const CefString& key) =0; + + /// + // Returns true if the object has a value with the specified identifier. + /// + /*--cef(capi_name=has_value_byindex,index_param=index)--*/ + virtual bool HasValue(int index) =0; + + /// + // Deletes the value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only and don't-delete values this method will return + // true even though deletion failed. + /// + /*--cef(capi_name=delete_value_bykey,optional_param=key)--*/ + virtual bool DeleteValue(const CefString& key) =0; + + /// + // Deletes the value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly, deletion fails + // or an exception is thrown. For read-only and don't-delete values this + // method will return true even though deletion failed. + /// + /*--cef(capi_name=delete_value_byindex,index_param=index)--*/ + virtual bool DeleteValue(int index) =0; + + /// + // Returns the value with the specified identifier on success. Returns NULL + // if this method is called incorrectly or an exception is thrown. + /// + /*--cef(capi_name=get_value_bykey,optional_param=key)--*/ + virtual CefRefPtr GetValue(const CefString& key) =0; + + /// + // Returns the value with the specified identifier on success. Returns NULL + // if this method is called incorrectly or an exception is thrown. + /// + /*--cef(capi_name=get_value_byindex,index_param=index)--*/ + virtual CefRefPtr GetValue(int index) =0; + + /// + // Associates a value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only values this method will return true even though + // assignment failed. + /// + /*--cef(capi_name=set_value_bykey,optional_param=key)--*/ + virtual bool SetValue(const CefString& key, CefRefPtr value, + PropertyAttribute attribute) =0; + + /// + // Associates a value with the specified identifier and returns true on + // success. Returns false if this method is called incorrectly or an exception + // is thrown. For read-only values this method will return true even though + // assignment failed. + /// + /*--cef(capi_name=set_value_byindex,index_param=index)--*/ + virtual bool SetValue(int index, CefRefPtr value) =0; + + /// + // Registers an identifier and returns true on success. Access to the + // identifier will be forwarded to the CefV8Accessor instance passed to + // CefV8Value::CreateObject(). Returns false if this method is called + // incorrectly or an exception is thrown. For read-only values this method + // will return true even though assignment failed. + /// + /*--cef(capi_name=set_value_byaccessor,optional_param=key)--*/ + virtual bool SetValue(const CefString& key, AccessControl settings, + PropertyAttribute attribute) =0; + + /// + // Read the keys for the object's values into the specified vector. Integer- + // based keys will also be returned as strings. + /// + /*--cef()--*/ + virtual bool GetKeys(std::vector& keys) =0; + + /// + // Sets the user data for this object and returns true on success. Returns + // false if this method is called incorrectly. This method can only be called + // on user created objects. + /// + /*--cef(optional_param=user_data)--*/ + virtual bool SetUserData(CefRefPtr user_data) =0; + + /// + // Returns the user data, if any, assigned to this object. + /// + /*--cef()--*/ + virtual CefRefPtr GetUserData() =0; + + /// + // Returns the amount of externally allocated memory registered for the + // object. + /// + /*--cef()--*/ + virtual int GetExternallyAllocatedMemory() =0; + + /// + // Adjusts the amount of registered external memory for the object. Used to + // give V8 an indication of the amount of externally allocated memory that is + // kept alive by JavaScript objects. V8 uses this information to decide when + // to perform global garbage collection. Each CefV8Value tracks the amount of + // external memory associated with it and automatically decreases the global + // total by the appropriate amount on its destruction. |change_in_bytes| + // specifies the number of bytes to adjust by. This method returns the number + // of bytes associated with the object after the adjustment. This method can + // only be called on user created objects. + /// + /*--cef()--*/ + virtual int AdjustExternallyAllocatedMemory(int change_in_bytes) =0; + + + // ARRAY METHODS - These methods are only available on arrays. + + /// + // Returns the number of elements in the array. + /// + /*--cef()--*/ + virtual int GetArrayLength() =0; + + + // FUNCTION METHODS - These methods are only available on functions. + + /// + // Returns the function name. + /// + /*--cef()--*/ + virtual CefString GetFunctionName() =0; + + /// + // Returns the function handler or NULL if not a CEF-created function. + /// + /*--cef()--*/ + virtual CefRefPtr GetFunctionHandler() =0; + + /// + // Execute the function using the current V8 context. This method should only + // be called from within the scope of a CefV8Handler or CefV8Accessor + // callback, or in combination with calling Enter() and Exit() on a stored + // CefV8Context reference. |object| is the receiver ('this' object) of the + // function. If |object| is empty the current context's global object will be + // used. |arguments| is the list of arguments that will be passed to the + // function. Returns the function return value on success. Returns NULL if + // this method is called incorrectly or an exception is thrown. + /// + /*--cef(optional_param=object)--*/ + virtual CefRefPtr ExecuteFunction( + CefRefPtr object, + const CefV8ValueList& arguments) =0; + + /// + // Execute the function using the specified V8 context. |object| is the + // receiver ('this' object) of the function. If |object| is empty the + // specified context's global object will be used. |arguments| is the list of + // arguments that will be passed to the function. Returns the function return + // value on success. Returns NULL if this method is called incorrectly or an + // exception is thrown. + /// + /*--cef(optional_param=object)--*/ + virtual CefRefPtr ExecuteFunctionWithContext( + CefRefPtr context, + CefRefPtr object, + const CefV8ValueList& arguments) =0; +}; + +/// +// Class representing a V8 stack trace handle. V8 handles can only be accessed +// from the thread on which they are created. Valid threads for creating a V8 +// handle include the render process main thread (TID_RENDERER) and WebWorker +// threads. A task runner for posting tasks on the associated thread can be +// retrieved via the CefV8Context::GetTaskRunner() method. +/// +/*--cef(source=library)--*/ +class CefV8StackTrace : public virtual CefBase { + public: + /// + // Returns the stack trace for the currently active context. |frame_limit| is + // the maximum number of frames that will be captured. + /// + /*--cef()--*/ + static CefRefPtr GetCurrent(int frame_limit); + + /// + // Returns true if the underlying handle is valid and it can be accessed on + // the current thread. Do not call any other methods if this method returns + // false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the number of stack frames. + /// + /*--cef()--*/ + virtual int GetFrameCount() =0; + + /// + // Returns the stack frame at the specified 0-based index. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame(int index) =0; +}; + +/// +// Class representing a V8 stack frame handle. V8 handles can only be accessed +// from the thread on which they are created. Valid threads for creating a V8 +// handle include the render process main thread (TID_RENDERER) and WebWorker +// threads. A task runner for posting tasks on the associated thread can be +// retrieved via the CefV8Context::GetTaskRunner() method. +/// +/*--cef(source=library)--*/ +class CefV8StackFrame : public virtual CefBase { + public: + /// + // Returns true if the underlying handle is valid and it can be accessed on + // the current thread. Do not call any other methods if this method returns + // false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns the name of the resource script that contains the function. + /// + /*--cef()--*/ + virtual CefString GetScriptName() =0; + + /// + // Returns the name of the resource script that contains the function or the + // sourceURL value if the script name is undefined and its source ends with + // a "//@ sourceURL=..." string. + /// + /*--cef()--*/ + virtual CefString GetScriptNameOrSourceURL() =0; + + /// + // Returns the name of the function. + /// + /*--cef()--*/ + virtual CefString GetFunctionName() =0; + + /// + // Returns the 1-based line number for the function call or 0 if unknown. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + /// + // Returns the 1-based column offset on the line for the function call or 0 if + // unknown. + /// + /*--cef()--*/ + virtual int GetColumn() =0; + + /// + // Returns true if the function was compiled using eval(). + /// + /*--cef()--*/ + virtual bool IsEval() =0; + + /// + // Returns true if the function was called as a constructor via "new". + /// + /*--cef()--*/ + virtual bool IsConstructor() =0; +}; + +#endif // CEF_INCLUDE_CEF_V8_H_ diff --git a/cefpython/cef3/include/cef_values.h b/cefpython/cef3/include/cef_values.h new file mode 100644 index 00000000..9a640ab7 --- /dev/null +++ b/cefpython/cef3/include/cef_values.h @@ -0,0 +1,471 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_VALUES_H_ +#define CEF_INCLUDE_CEF_VALUES_H_ +#pragma once + +#include +#include "include/cef_base.h" + +class CefDictionaryValue; +class CefListValue; + +typedef cef_value_type_t CefValueType; + +/// +// Class representing a binary value. Can be used on any process and thread. +/// +/*--cef(source=library)--*/ +class CefBinaryValue : public virtual CefBase { + public: + /// + // Creates a new object that is not owned by any other object. The specified + // |data| will be copied. + /// + /*--cef()--*/ + static CefRefPtr Create(const void* data, + size_t data_size); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if this object is currently owned by another object. + /// + /*--cef()--*/ + virtual bool IsOwned() =0; + + /// + // Returns a copy of this object. The data in this object will also be copied. + /// + /*--cef()--*/ + virtual CefRefPtr Copy() =0; + + /// + // Returns the data size. + /// + /*--cef()--*/ + virtual size_t GetSize() =0; + + /// + // Read up to |buffer_size| number of bytes into |buffer|. Reading begins at + // the specified byte |data_offset|. Returns the number of bytes read. + /// + /*--cef()--*/ + virtual size_t GetData(void* buffer, + size_t buffer_size, + size_t data_offset) =0; +}; + + +/// +// Class representing a dictionary value. Can be used on any process and thread. +/// +/*--cef(source=library)--*/ +class CefDictionaryValue : public virtual CefBase { + public: + typedef std::vector KeyList; + + /// + // Creates a new object that is not owned by any other object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if this object is currently owned by another object. + /// + /*--cef()--*/ + virtual bool IsOwned() =0; + + /// + // Returns true if the values of this object are read-only. Some APIs may + // expose read-only objects. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Returns a writable copy of this object. If |exclude_empty_children| is true + // any empty dictionaries or lists will be excluded from the copy. + /// + /*--cef()--*/ + virtual CefRefPtr Copy(bool exclude_empty_children) =0; + + /// + // Returns the number of values. + /// + /*--cef()--*/ + virtual size_t GetSize() =0; + + /// + // Removes all values. Returns true on success. + /// + /*--cef()--*/ + virtual bool Clear() =0; + + /// + // Returns true if the current dictionary has a value for the given key. + /// + /*--cef()--*/ + virtual bool HasKey(const CefString& key) =0; + + /// + // Reads all keys for this dictionary into the specified vector. + /// + /*--cef()--*/ + virtual bool GetKeys(KeyList& keys) =0; + + /// + // Removes the value at the specified key. Returns true is the value was + // removed successfully. + /// + /*--cef()--*/ + virtual bool Remove(const CefString& key) =0; + + /// + // Returns the value type for the specified key. + /// + /*--cef(default_retval=VTYPE_INVALID)--*/ + virtual CefValueType GetType(const CefString& key) =0; + + /// + // Returns the value at the specified key as type bool. + /// + /*--cef()--*/ + virtual bool GetBool(const CefString& key) =0; + + /// + // Returns the value at the specified key as type int. + /// + /*--cef()--*/ + virtual int GetInt(const CefString& key) =0; + + /// + // Returns the value at the specified key as type double. + /// + /*--cef()--*/ + virtual double GetDouble(const CefString& key) =0; + + /// + // Returns the value at the specified key as type string. + /// + /*--cef()--*/ + virtual CefString GetString(const CefString& key) =0; + + /// + // Returns the value at the specified key as type binary. + /// + /*--cef()--*/ + virtual CefRefPtr GetBinary(const CefString& key) =0; + + /// + // Returns the value at the specified key as type dictionary. + /// + /*--cef()--*/ + virtual CefRefPtr GetDictionary(const CefString& key) =0; + + /// + // Returns the value at the specified key as type list. + /// + /*--cef()--*/ + virtual CefRefPtr GetList(const CefString& key) =0; + + /// + // Sets the value at the specified key as type null. Returns true if the + // value was set successfully. + /// + /*--cef()--*/ + virtual bool SetNull(const CefString& key) =0; + + /// + // Sets the value at the specified key as type bool. Returns true if the + // value was set successfully. + /// + /*--cef()--*/ + virtual bool SetBool(const CefString& key, bool value) =0; + + /// + // Sets the value at the specified key as type int. Returns true if the + // value was set successfully. + /// + /*--cef()--*/ + virtual bool SetInt(const CefString& key, int value) =0; + + /// + // Sets the value at the specified key as type double. Returns true if the + // value was set successfully. + /// + /*--cef()--*/ + virtual bool SetDouble(const CefString& key, double value) =0; + + /// + // Sets the value at the specified key as type string. Returns true if the + // value was set successfully. + /// + /*--cef(optional_param=value)--*/ + virtual bool SetString(const CefString& key, const CefString& value) =0; + + /// + // Sets the value at the specified key as type binary. Returns true if the + // value was set successfully. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef()--*/ + virtual bool SetBinary(const CefString& key, + CefRefPtr value) =0; + + /// + // Sets the value at the specified key as type dict. Returns true if the + // value was set successfully. After calling this method the |value| object + // will no longer be valid. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef()--*/ + virtual bool SetDictionary(const CefString& key, + CefRefPtr value) =0; + + /// + // Sets the value at the specified key as type list. Returns true if the + // value was set successfully. After calling this method the |value| object + // will no longer be valid. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef()--*/ + virtual bool SetList(const CefString& key, + CefRefPtr value) =0; +}; + + +/// +// Class representing a list value. Can be used on any process and thread. +/// +/*--cef(source=library)--*/ +class CefListValue : public virtual CefBase { + public: + /// + // Creates a new object that is not owned by any other object. + /// + /*--cef()--*/ + static CefRefPtr Create(); + + /// + // Returns true if this object is valid. Do not call any other methods if this + // method returns false. + /// + /*--cef()--*/ + virtual bool IsValid() =0; + + /// + // Returns true if this object is currently owned by another object. + /// + /*--cef()--*/ + virtual bool IsOwned() =0; + + /// + // Returns true if the values of this object are read-only. Some APIs may + // expose read-only objects. + /// + /*--cef()--*/ + virtual bool IsReadOnly() =0; + + /// + // Returns a writable copy of this object. + /// + /*--cef()--*/ + virtual CefRefPtr Copy() =0; + + /// + // Sets the number of values. If the number of values is expanded all + // new value slots will default to type null. Returns true on success. + /// + /*--cef()--*/ + virtual bool SetSize(size_t size) =0; + + /// + // Returns the number of values. + /// + /*--cef()--*/ + virtual size_t GetSize() =0; + + /// + // Removes all values. Returns true on success. + /// + /*--cef()--*/ + virtual bool Clear() =0; + + /// + // Removes the value at the specified index. + /// + /*--cef(index_param=index)--*/ + virtual bool Remove(int index) =0; + + /// + // Returns the value type at the specified index. + /// + /*--cef(default_retval=VTYPE_INVALID,index_param=index)--*/ + virtual CefValueType GetType(int index) =0; + + /// + // Returns the value at the specified index as type bool. + /// + /*--cef(index_param=index)--*/ + virtual bool GetBool(int index) =0; + + /// + // Returns the value at the specified index as type int. + /// + /*--cef(index_param=index)--*/ + virtual int GetInt(int index) =0; + + /// + // Returns the value at the specified index as type double. + /// + /*--cef(index_param=index)--*/ + virtual double GetDouble(int index) =0; + + /// + // Returns the value at the specified index as type string. + /// + /*--cef(index_param=index)--*/ + virtual CefString GetString(int index) =0; + + /// + // Returns the value at the specified index as type binary. + /// + /*--cef(index_param=index)--*/ + virtual CefRefPtr GetBinary(int index) =0; + + /// + // Returns the value at the specified index as type dictionary. + /// + /*--cef(index_param=index)--*/ + virtual CefRefPtr GetDictionary(int index) =0; + + /// + // Returns the value at the specified index as type list. + /// + /*--cef(index_param=index)--*/ + virtual CefRefPtr GetList(int index) =0; + + /// + // Sets the value at the specified index as type null. Returns true if the + // value was set successfully. + /// + /*--cef(index_param=index)--*/ + virtual bool SetNull(int index) =0; + + /// + // Sets the value at the specified index as type bool. Returns true if the + // value was set successfully. + /// + /*--cef(index_param=index)--*/ + virtual bool SetBool(int index, bool value) =0; + + /// + // Sets the value at the specified index as type int. Returns true if the + // value was set successfully. + /// + /*--cef(index_param=index)--*/ + virtual bool SetInt(int index, int value) =0; + + /// + // Sets the value at the specified index as type double. Returns true if the + // value was set successfully. + /// + /*--cef(index_param=index)--*/ + virtual bool SetDouble(int index, double value) =0; + + /// + // Sets the value at the specified index as type string. Returns true if the + // value was set successfully. + /// + /*--cef(optional_param=value,index_param=index)--*/ + virtual bool SetString(int index, const CefString& value) =0; + + /// + // Sets the value at the specified index as type binary. Returns true if the + // value was set successfully. After calling this method the |value| object + // will no longer be valid. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef(index_param=index)--*/ + virtual bool SetBinary(int index, CefRefPtr value) =0; + + /// + // Sets the value at the specified index as type dict. Returns true if the + // value was set successfully. After calling this method the |value| object + // will no longer be valid. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef(index_param=index)--*/ + virtual bool SetDictionary(int index, CefRefPtr value) =0; + + /// + // Sets the value at the specified index as type list. Returns true if the + // value was set successfully. After calling this method the |value| object + // will no longer be valid. If |value| is currently owned by another object + // then the value will be copied and the |value| reference will not change. + // Otherwise, ownership will be transferred to this object and the |value| + // reference will be invalidated. + /// + /*--cef(index_param=index)--*/ + virtual bool SetList(int index, CefRefPtr value) =0; +}; + +#endif // CEF_INCLUDE_CEF_VALUES_H_ diff --git a/cefpython/cef3/include/cef_web_plugin.h b/cefpython/cef3/include/cef_web_plugin.h new file mode 100644 index 00000000..0ff2b8ea --- /dev/null +++ b/cefpython/cef3/include/cef_web_plugin.h @@ -0,0 +1,178 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_WEB_PLUGIN_H_ +#define CEF_INCLUDE_CEF_WEB_PLUGIN_H_ + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Information about a specific web plugin. +/// +/*--cef(source=library)--*/ +class CefWebPluginInfo : public virtual CefBase { + public: + /// + // Returns the plugin name (i.e. Flash). + /// + /*--cef()--*/ + virtual CefString GetName() =0; + + /// + // Returns the plugin file path (DLL/bundle/library). + /// + /*--cef()--*/ + virtual CefString GetPath() =0; + + /// + // Returns the version of the plugin (may be OS-specific). + /// + /*--cef()--*/ + virtual CefString GetVersion() =0; + + /// + // Returns a description of the plugin from the version information. + /// + /*--cef()--*/ + virtual CefString GetDescription() =0; +}; + +/// +// Interface to implement for visiting web plugin information. The methods of +// this class will be called on the browser process UI thread. +/// +/*--cef(source=client)--*/ +class CefWebPluginInfoVisitor : public virtual CefBase { + public: + /// + // Method that will be called once for each plugin. |count| is the 0-based + // index for the current plugin. |total| is the total number of plugins. + // Return false to stop visiting plugins. This method may never be called if + // no plugins are found. + /// + /*--cef()--*/ + virtual bool Visit(CefRefPtr info, int count, int total) =0; +}; + +/// +// Visit web plugin information. Can be called on any thread in the browser +// process. +/// +/*--cef()--*/ +void CefVisitWebPluginInfo(CefRefPtr visitor); + +/// +// Cause the plugin list to refresh the next time it is accessed regardless +// of whether it has already been loaded. Can be called on any thread in the +// browser process. +/// +/*--cef()--*/ +void CefRefreshWebPlugins(); + +/// +// Add a plugin path (directory + file). This change may not take affect until +// after CefRefreshWebPlugins() is called. Can be called on any thread in the +// browser process. +/// +/*--cef()--*/ +void CefAddWebPluginPath(const CefString& path); + +/// +// Add a plugin directory. This change may not take affect until after +// CefRefreshWebPlugins() is called. Can be called on any thread in the browser +// process. +/// +/*--cef()--*/ +void CefAddWebPluginDirectory(const CefString& dir); + +/// +// Remove a plugin path (directory + file). This change may not take affect +// until after CefRefreshWebPlugins() is called. Can be called on any thread in +// the browser process. +/// +/*--cef()--*/ +void CefRemoveWebPluginPath(const CefString& path); + +/// +// Unregister an internal plugin. This may be undone the next time +// CefRefreshWebPlugins() is called. Can be called on any thread in the browser +// process. +/// +/*--cef()--*/ +void CefUnregisterInternalWebPlugin(const CefString& path); + +/// +// Force a plugin to shutdown. Can be called on any thread in the browser +// process but will be executed on the IO thread. +/// +/*--cef()--*/ +void CefForceWebPluginShutdown(const CefString& path); + +/// +// Register a plugin crash. Can be called on any thread in the browser process +// but will be executed on the IO thread. +/// +/*--cef()--*/ +void CefRegisterWebPluginCrash(const CefString& path); + +/// +// Interface to implement for receiving unstable plugin information. The methods +// of this class will be called on the browser process IO thread. +/// +/*--cef(source=client)--*/ +class CefWebPluginUnstableCallback : public virtual CefBase { + public: + /// + // Method that will be called for the requested plugin. |unstable| will be + // true if the plugin has reached the crash count threshold of 3 times in 120 + // seconds. + /// + /*--cef()--*/ + virtual void IsUnstable(const CefString& path, + bool unstable) =0; +}; + +/// +// Query if a plugin is unstable. Can be called on any thread in the browser +// process. +/// +/*--cef()--*/ +void CefIsWebPluginUnstable(const CefString& path, + CefRefPtr callback); + + +#endif // CEF_INCLUDE_CEF_WEB_PLUGIN_H_ diff --git a/cefpython/cef3/include/cef_xml_reader.h b/cefpython/cef3/include/cef_xml_reader.h new file mode 100644 index 00000000..86be8bac --- /dev/null +++ b/cefpython/cef3/include/cef_xml_reader.h @@ -0,0 +1,268 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_XML_READER_H_ +#define CEF_INCLUDE_CEF_XML_READER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Class that supports the reading of XML data via the libxml streaming API. +// The methods of this class should only be called on the thread that creates +// the object. +/// +/*--cef(source=library)--*/ +class CefXmlReader : public virtual CefBase { + public: + typedef cef_xml_encoding_type_t EncodingType; + typedef cef_xml_node_type_t NodeType; + + /// + // Create a new CefXmlReader object. The returned object's methods can only + // be called from the thread that created the object. + /// + /*--cef()--*/ + static CefRefPtr Create(CefRefPtr stream, + EncodingType encodingType, + const CefString& URI); + + /// + // Moves the cursor to the next node in the document. This method must be + // called at least once to set the current cursor position. Returns true if + // the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextNode() =0; + + /// + // Close the document. This should be called directly to ensure that cleanup + // occurs on the correct thread. + /// + /*--cef()--*/ + virtual bool Close() =0; + + /// + // Returns true if an error has been reported by the XML parser. + /// + /*--cef()--*/ + virtual bool HasError() =0; + + /// + // Returns the error string. + /// + /*--cef()--*/ + virtual CefString GetError() =0; + + + // The below methods retrieve data for the node at the current cursor + // position. + + /// + // Returns the node type. + /// + /*--cef(default_retval=XML_NODE_UNSUPPORTED)--*/ + virtual NodeType GetType() =0; + + /// + // Returns the node depth. Depth starts at 0 for the root node. + /// + /*--cef()--*/ + virtual int GetDepth() =0; + + /// + // Returns the local name. See + // http://www.w3.org/TR/REC-xml-names/#NT-LocalPart for additional details. + /// + /*--cef()--*/ + virtual CefString GetLocalName() =0; + + /// + // Returns the namespace prefix. See http://www.w3.org/TR/REC-xml-names/ for + // additional details. + /// + /*--cef()--*/ + virtual CefString GetPrefix() =0; + + /// + // Returns the qualified name, equal to (Prefix:)LocalName. See + // http://www.w3.org/TR/REC-xml-names/#ns-qualnames for additional details. + /// + /*--cef()--*/ + virtual CefString GetQualifiedName() =0; + + /// + // Returns the URI defining the namespace associated with the node. See + // http://www.w3.org/TR/REC-xml-names/ for additional details. + /// + /*--cef()--*/ + virtual CefString GetNamespaceURI() =0; + + /// + // Returns the base URI of the node. See http://www.w3.org/TR/xmlbase/ for + // additional details. + /// + /*--cef()--*/ + virtual CefString GetBaseURI() =0; + + /// + // Returns the xml:lang scope within which the node resides. See + // http://www.w3.org/TR/REC-xml/#sec-lang-tag for additional details. + /// + /*--cef()--*/ + virtual CefString GetXmlLang() =0; + + /// + // Returns true if the node represents an empty element. is considered + // empty but is not. + /// + /*--cef()--*/ + virtual bool IsEmptyElement() =0; + + /// + // Returns true if the node has a text value. + /// + /*--cef()--*/ + virtual bool HasValue() =0; + + /// + // Returns the text value. + /// + /*--cef()--*/ + virtual CefString GetValue() =0; + + /// + // Returns true if the node has attributes. + /// + /*--cef()--*/ + virtual bool HasAttributes() =0; + + /// + // Returns the number of attributes. + /// + /*--cef()--*/ + virtual size_t GetAttributeCount() =0; + + /// + // Returns the value of the attribute at the specified 0-based index. + /// + /*--cef(capi_name=get_attribute_byindex,index_param=index)--*/ + virtual CefString GetAttribute(int index) =0; + + /// + // Returns the value of the attribute with the specified qualified name. + /// + /*--cef(capi_name=get_attribute_byqname)--*/ + virtual CefString GetAttribute(const CefString& qualifiedName) =0; + + /// + // Returns the value of the attribute with the specified local name and + // namespace URI. + /// + /*--cef(capi_name=get_attribute_bylname)--*/ + virtual CefString GetAttribute(const CefString& localName, + const CefString& namespaceURI) =0; + + /// + // Returns an XML representation of the current node's children. + /// + /*--cef()--*/ + virtual CefString GetInnerXml() =0; + + /// + // Returns an XML representation of the current node including its children. + /// + /*--cef()--*/ + virtual CefString GetOuterXml() =0; + + /// + // Returns the line number for the current node. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + + // Attribute nodes are not traversed by default. The below methods can be + // used to move the cursor to an attribute node. MoveToCarryingElement() can + // be called afterwards to return the cursor to the carrying element. The + // depth of an attribute node will be 1 + the depth of the carrying element. + + /// + // Moves the cursor to the attribute at the specified 0-based index. Returns + // true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_byindex,index_param=index)--*/ + virtual bool MoveToAttribute(int index) =0; + + /// + // Moves the cursor to the attribute with the specified qualified name. + // Returns true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_byqname)--*/ + virtual bool MoveToAttribute(const CefString& qualifiedName) =0; + + /// + // Moves the cursor to the attribute with the specified local name and + // namespace URI. Returns true if the cursor position was set successfully. + /// + /*--cef(capi_name=move_to_attribute_bylname)--*/ + virtual bool MoveToAttribute(const CefString& localName, + const CefString& namespaceURI) =0; + + /// + // Moves the cursor to the first attribute in the current element. Returns + // true if the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFirstAttribute() =0; + + /// + // Moves the cursor to the next attribute in the current element. Returns + // true if the cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextAttribute() =0; + + /// + // Moves the cursor back to the carrying element. Returns true if the cursor + // position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToCarryingElement() =0; +}; + +#endif // CEF_INCLUDE_CEF_XML_READER_H_ diff --git a/cefpython/cef3/include/cef_zip_reader.h b/cefpython/cef3/include/cef_zip_reader.h new file mode 100644 index 00000000..1fe02b91 --- /dev/null +++ b/cefpython/cef3/include/cef_zip_reader.h @@ -0,0 +1,141 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_ZIP_READER_H_ +#define CEF_INCLUDE_CEF_ZIP_READER_H_ + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Class that supports the reading of zip archives via the zlib unzip API. +// The methods of this class should only be called on the thread that creates +// the object. +/// +/*--cef(source=library)--*/ +class CefZipReader : public virtual CefBase { + public: + /// + // Create a new CefZipReader object. The returned object's methods can only + // be called from the thread that created the object. + /// + /*--cef()--*/ + static CefRefPtr Create(CefRefPtr stream); + + /// + // Moves the cursor to the first file in the archive. Returns true if the + // cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFirstFile() =0; + + /// + // Moves the cursor to the next file in the archive. Returns true if the + // cursor position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToNextFile() =0; + + /// + // Moves the cursor to the specified file in the archive. If |caseSensitive| + // is true then the search will be case sensitive. Returns true if the cursor + // position was set successfully. + /// + /*--cef()--*/ + virtual bool MoveToFile(const CefString& fileName, bool caseSensitive) =0; + + /// + // Closes the archive. This should be called directly to ensure that cleanup + // occurs on the correct thread. + /// + /*--cef()--*/ + virtual bool Close() =0; + + + // The below methods act on the file at the current cursor position. + + /// + // Returns the name of the file. + /// + /*--cef()--*/ + virtual CefString GetFileName() =0; + + /// + // Returns the uncompressed size of the file. + /// + /*--cef()--*/ + virtual int64 GetFileSize() =0; + + /// + // Returns the last modified timestamp for the file. + /// + /*--cef()--*/ + virtual time_t GetFileLastModified() =0; + + /// + // Opens the file for reading of uncompressed data. A read password may + // optionally be specified. + /// + /*--cef(optional_param=password)--*/ + virtual bool OpenFile(const CefString& password) =0; + + /// + // Closes the file. + /// + /*--cef()--*/ + virtual bool CloseFile() =0; + + /// + // Read uncompressed file contents into the specified buffer. Returns < 0 if + // an error occurred, 0 if at the end of file, or the number of bytes read. + /// + /*--cef()--*/ + virtual int ReadFile(void* buffer, size_t bufferSize) =0; + + /// + // Returns the current offset in the uncompressed file contents. + /// + /*--cef()--*/ + virtual int64 Tell() =0; + + /// + // Returns true if at end of the file contents. + /// + /*--cef()--*/ + virtual bool Eof() =0; +}; + +#endif // CEF_INCLUDE_CEF_ZIP_READER_H_ diff --git a/cefpython/cef3/include/internal/cef_build.h b/cefpython/cef3/include/internal/cef_build.h new file mode 100644 index 00000000..4b8c5454 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_build.h @@ -0,0 +1,129 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ +#define CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ +#pragma once + +#if defined(BUILDING_CEF_SHARED) + +#include "base/compiler_specific.h" + +#else // !BUILDING_CEF_SHARED + +#if defined(_WIN32) +#ifndef OS_WIN +#define OS_WIN 1 +#endif +#elif defined(__APPLE__) +#ifndef OS_MACOSX +#define OS_MACOSX 1 +#endif +#elif defined(__linux__) +#ifndef OS_LINUX +#define OS_LINUX 1 +#endif +#else +#error Please add support for your platform in cef_build.h +#endif + +// For access to standard POSIXish features, use OS_POSIX instead of a +// more specific macro. +#if defined(OS_MACOSX) || defined(OS_LINUX) +#ifndef OS_POSIX +#define OS_POSIX 1 +#endif +#endif + +// Compiler detection. +#if defined(__GNUC__) +#ifndef COMPILER_GCC +#define COMPILER_GCC 1 +#endif +#elif defined(_MSC_VER) +#ifndef COMPILER_MSVC +#define COMPILER_MSVC 1 +#endif +#else +#error Please add support for your compiler in cef_build.h +#endif + +// Annotate a virtual method indicating it must be overriding a virtual +// method in the parent class. +// Use like: +// virtual void foo() OVERRIDE; +#ifndef OVERRIDE +#if defined(COMPILER_MSVC) +#define OVERRIDE override +#elif defined(__clang__) +#define OVERRIDE override +#else +#define OVERRIDE +#endif +#endif + +#ifndef ALLOW_THIS_IN_INITIALIZER_LIST +#if defined(COMPILER_MSVC) + +// MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. +// The warning remains disabled until popped by MSVC_POP_WARNING. +#define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ + __pragma(warning(disable:n)) + +// MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level +// remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all +// warnings. +#define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) + +// Pop effects of innermost MSVC_PUSH_* macro. +#define MSVC_POP_WARNING() __pragma(warning(pop)) + +// Allows |this| to be passed as an argument in constructor initializer lists. +// This uses push/pop instead of the seemingly simpler suppress feature to avoid +// having the warning be disabled for more than just |code|. +// +// Example usage: +// Foo::Foo() : x(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(y(this)), z(3) {} +// +// Compiler warning C4355: 'this': used in base member initializer list: +// http://msdn.microsoft.com/en-us/library/3c594ae3(VS.80).aspx +#define ALLOW_THIS_IN_INITIALIZER_LIST(code) MSVC_PUSH_DISABLE_WARNING(4355) \ + code \ + MSVC_POP_WARNING() +#else // !COMPILER_MSVC + +#define ALLOW_THIS_IN_INITIALIZER_LIST(code) code + +#endif // !COMPILER_MSVC +#endif + +#endif // !BUILDING_CEF_SHARED + +#endif // CEF_INCLUDE_INTERNAL_CEF_BUILD_H_ diff --git a/cefpython/cef3/include/internal/cef_export.h b/cefpython/cef3/include/internal/cef_export.h new file mode 100644 index 00000000..d333a5db --- /dev/null +++ b/cefpython/cef3/include/internal/cef_export.h @@ -0,0 +1,55 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights +// reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ +#define CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(COMPILER_MSVC) + +#ifdef BUILDING_CEF_SHARED +#define CEF_EXPORT __declspec(dllexport) +#elif USING_CEF_SHARED +#define CEF_EXPORT __declspec(dllimport) +#else +#define CEF_EXPORT +#endif +#define CEF_CALLBACK __stdcall + +#elif defined(COMPILER_GCC) + +#define CEF_EXPORT __attribute__ ((visibility("default"))) +#define CEF_CALLBACK + +#endif // COMPILER_GCC + +#endif // CEF_INCLUDE_INTERNAL_CEF_EXPORT_H_ diff --git a/cefpython/cef3/include/internal/cef_linux.h b/cefpython/cef3/include/internal/cef_linux.h new file mode 100644 index 00000000..ddf15ce5 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_linux.h @@ -0,0 +1,144 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ +#define CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ +#pragma once + +#if defined(OS_LINUX) +#include +#include "include/internal/cef_types_linux.h" +#include "include/internal/cef_types_wrappers.h" + +// Atomic increment and decrement. +inline long CefAtomicIncrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_add_and_fetch(pDest, 1); +} +inline long CefAtomicDecrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_sub_and_fetch(pDest, 1); +} + +// Critical section wrapper. +class CefCriticalSection { + public: + CefCriticalSection() { + pthread_mutexattr_init(&attr_); + pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock_, &attr_); + } + virtual ~CefCriticalSection() { + pthread_mutex_destroy(&lock_); + pthread_mutexattr_destroy(&attr_); + } + void Lock() { + pthread_mutex_lock(&lock_); + } + void Unlock() { + pthread_mutex_unlock(&lock_); + } + + pthread_mutex_t lock_; + pthread_mutexattr_t attr_; +}; + +// Handle types. +#define CefCursorHandle cef_cursor_handle_t +#define CefEventHandle cef_event_handle_t +#define CefWindowHandle cef_window_handle_t +#define CefTextInputContext cef_text_input_context_t + +struct CefMainArgsTraits { + typedef cef_main_args_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->argc = src->argc; + target->argv = src->argv; + } +}; + +// Class representing CefExecuteProcess arguments. +class CefMainArgs : public CefStructBase { + public: + typedef CefStructBase parent; + + CefMainArgs() : parent() {} + explicit CefMainArgs(const cef_main_args_t& r) : parent(r) {} + explicit CefMainArgs(const CefMainArgs& r) : parent(r) {} + CefMainArgs(int argc_arg, char** argv_arg) : parent() { + argc = argc_arg; + argv = argv_arg; + } +}; + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->parent_widget = src->parent_widget; + target->window_rendering_disabled = src->window_rendering_disabled; + target->transparent_painting = src->transparent_painting; + target->widget = src->widget; + } +}; + +// Class representing window information. +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(CefWindowHandle ParentWidget) { + parent_widget = ParentWidget; + } + + void SetTransparentPainting(bool transparentPainting) { + transparent_painting = transparentPainting; + } + + void SetAsOffScreen(CefWindowHandle ParentWidget) { + window_rendering_disabled = true; + parent_widget = ParentWidget; + } +}; + +#endif // OS_LINUX + +#endif // CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ diff --git a/cefpython/cef3/include/internal/cef_mac.h b/cefpython/cef3/include/internal/cef_mac.h new file mode 100644 index 00000000..352a5c2b --- /dev/null +++ b/cefpython/cef3/include/internal/cef_mac.h @@ -0,0 +1,160 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_MAC_H_ +#define CEF_INCLUDE_INTERNAL_CEF_MAC_H_ +#pragma once + +#if defined(OS_MACOSX) +#include +#include "include/internal/cef_types_mac.h" +#include "include/internal/cef_types_wrappers.h" + +// Atomic increment and decrement. +inline long CefAtomicIncrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_add_and_fetch(pDest, 1); +} +inline long CefAtomicDecrement(long volatile *pDest) { // NOLINT(runtime/int) + return __sync_sub_and_fetch(pDest, 1); +} + +// Critical section wrapper. +class CefCriticalSection { + public: + CefCriticalSection() { + pthread_mutexattr_init(&attr_); + pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock_, &attr_); + } + virtual ~CefCriticalSection() { + pthread_mutex_destroy(&lock_); + pthread_mutexattr_destroy(&attr_); + } + void Lock() { + pthread_mutex_lock(&lock_); + } + void Unlock() { + pthread_mutex_unlock(&lock_); + } + + pthread_mutex_t lock_; + pthread_mutexattr_t attr_; +}; + +// Handle types. +#define CefCursorHandle cef_cursor_handle_t +#define CefEventHandle cef_event_handle_t +#define CefWindowHandle cef_window_handle_t +#define CefTextInputContext cef_text_input_context_t + +struct CefMainArgsTraits { + typedef cef_main_args_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->argc = src->argc; + target->argv = src->argv; + } +}; + +// Class representing CefExecuteProcess arguments. +class CefMainArgs : public CefStructBase { + public: + typedef CefStructBase parent; + + CefMainArgs() : parent() {} + explicit CefMainArgs(const cef_main_args_t& r) : parent(r) {} + explicit CefMainArgs(const CefMainArgs& r) : parent(r) {} + CefMainArgs(int argc, char** argv) : parent() { + this->argc = argc; + this->argv = argv; + } +}; + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->window_name); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->view = src->view; + target->parent_view = src->parent_view; + cef_string_set(src->window_name.str, src->window_name.length, + &target->window_name, copy); + target->x = src->x; + target->y = src->y; + target->width = src->width; + target->height = src->height; + target->hidden = src->hidden; + target->transparent_painting = src->transparent_painting; + target->window_rendering_disabled = src->window_rendering_disabled; + } +}; + +// Class representing window information. +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(CefWindowHandle ParentView, int x, int y, int width, + int height) { + parent_view = ParentView; + this->x = x; + this->y = y; + this->width = width; + this->height = height; + hidden = false; + } + + void SetTransparentPainting(bool transparentPainting) { + transparent_painting = transparentPainting; + } + + void SetAsOffScreen(NSView* view) { + window_rendering_disabled = true; + parent_view = view; + } +}; + +#endif // OS_MACOSX + +#endif // CEF_INCLUDE_INTERNAL_CEF_MAC_H_ diff --git a/cefpython/cef3/include/internal/cef_ptr.h b/cefpython/cef3/include/internal/cef_ptr.h new file mode 100644 index 00000000..fcbe69e5 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_ptr.h @@ -0,0 +1,199 @@ +// Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2008 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_PTR_H_ +#define CEF_INCLUDE_INTERNAL_CEF_PTR_H_ +#pragma once + +#include + +/// +// Smart pointer implementation borrowed from base/ref_counted.h +//

+// A smart pointer class for reference counted objects. Use this class instead +// of calling AddRef and Release manually on a reference counted object to +// avoid common memory leaks caused by forgetting to Release an object +// reference. Sample usage: +//

+//   class MyFoo : public CefBase {
+//    ...
+//   };
+//
+//   void some_function() {
+//     // The MyFoo object that |foo| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//     foo->Method(param);
+//     // |foo| is released when this function returns
+//   }
+//
+//   void some_other_function() {
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//     ...
+//     foo = NULL;  // explicitly releases |foo|
+//     ...
+//     if (foo)
+//       foo->Method(param);
+//   }
+// 
+// The above examples show how CefRefPtr<T> acts like a pointer to T. +// Given two CefRefPtr<T> classes, it is also possible to exchange +// references between the two objects, like so: +//
+//   {
+//     CefRefPtr<MyFoo> a = new MyFoo();
+//     CefRefPtr<MyFoo> b;
+//
+//     b.swap(a);
+//     // now, |b| references the MyFoo object, and |a| references NULL.
+//   }
+// 
+// To make both |a| and |b| in the above example reference the same MyFoo +// object, simply use the assignment operator: +//
+//   {
+//     CefRefPtr<MyFoo> a = new MyFoo();
+//     CefRefPtr<MyFoo> b;
+//
+//     b = a;
+//     // now, |a| and |b| each own a reference to the same MyFoo object.
+//     // the reference count of the underlying MyFoo object will be 2.
+//   }
+// 
+// Reference counted objects can also be passed as function parameters and +// used as function return values: +//
+//   void some_func_with_param(CefRefPtr<MyFoo> param) {
+//     // A reference is added to the MyFoo object that |param| represents
+//     // during the scope of some_func_with_param() and released when
+//     // some_func_with_param() goes out of scope.
+//   }
+//
+//   CefRefPtr<MyFoo> some_func_with_retval() {
+//     // The MyFoo object that |foox| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foox = new MyFoo();
+//
+//     // Creating the return value adds an additional reference.
+//     return foox;
+//
+//     // When some_func_with_retval() goes out of scope the original |foox|
+//     // reference is released.
+//   }
+//
+//   void and_another_function() {
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//
+//     // pass |foo| as a parameter.
+//     some_function(foo);
+//
+//     CefRefPtr<MyFoo> foo2 = some_func_with_retval();
+//     // Now, since we kept a reference to the some_func_with_retval() return
+//     // value, |foo2| is the only class pointing to the MyFoo object created
+//     in some_func_with_retval(), and it has a reference count of 1.
+//
+//     some_func_with_retval();
+//     // Now, since we didn't keep a reference to the some_func_with_retval()
+//     // return value, the MyFoo object created in some_func_with_retval()
+//     // will automatically be released.
+//   }
+// 
+// And in standard containers: +//
+//   {
+//      // Create a vector that holds MyFoo objects.
+//      std::vector<CefRefPtr<MyFoo> > MyFooVec;
+//
+//     // The MyFoo object that |foo| represents starts with a single
+//     // reference.
+//     CefRefPtr<MyFoo> foo = new MyFoo();
+//
+//     // When the MyFoo object is added to |MyFooVec| the reference count
+//     // is increased to 2.
+//     MyFooVec.push_back(foo);
+//   }
+// 
+//

+/// +template +class CefRefPtr { + public: + CefRefPtr() : ptr_(NULL) { + } + + CefRefPtr(T* p) : ptr_(p) { // NOLINT(runtime/explicit) + if (ptr_) + ptr_->AddRef(); + } + + CefRefPtr(const CefRefPtr& r) : ptr_(r.ptr_) { + if (ptr_) + ptr_->AddRef(); + } + + ~CefRefPtr() { + if (ptr_) + ptr_->Release(); + } + + T* get() const { return ptr_; } + operator T*() const { return ptr_; } + T* operator->() const { return ptr_; } + + CefRefPtr& operator=(T* p) { + // AddRef first so that self assignment should work + if (p) + p->AddRef(); + if (ptr_ ) + ptr_ ->Release(); + ptr_ = p; + return *this; + } + + CefRefPtr& operator=(const CefRefPtr& r) { + return *this = r.ptr_; + } + + void swap(T** pp) { + T* p = ptr_; + ptr_ = *pp; + *pp = p; + } + + void swap(CefRefPtr& r) { + swap(&r.ptr_); // NOLINT(build/include_what_you_use) + } + + private: + T* ptr_; +}; + +#endif // CEF_INCLUDE_INTERNAL_CEF_PTR_H_ diff --git a/cefpython/cef3/include/internal/cef_string.h b/cefpython/cef3/include/internal/cef_string.h new file mode 100644 index 00000000..a7876fe5 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string.h @@ -0,0 +1,113 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_H_ +#pragma once + +// The CEF interface is built with one string type as the default. Comment out +// all but one of the CEF_STRING_TYPE_* defines below to specify the default. +// If you change the default you MUST recompile all of CEF. + +// Build with the UTF8 string type as default. +// #define CEF_STRING_TYPE_UTF8 1 + +// Build with the UTF16 string type as default. +#define CEF_STRING_TYPE_UTF16 1 + +// Build with the wide string type as default. +// #define CEF_STRING_TYPE_WIDE 1 + + +#include "include/internal/cef_string_types.h" + +#ifdef __cplusplus +#include "include/internal/cef_string_wrappers.h" +#if defined(CEF_STRING_TYPE_UTF16) +typedef CefStringUTF16 CefString; +#elif defined(CEF_STRING_TYPE_UTF8) +typedef CefStringUTF8 CefString; +#elif defined(CEF_STRING_TYPE_WIDE) +typedef CefStringWide CefString; +#endif +#endif // __cplusplus + +#if defined(CEF_STRING_TYPE_UTF8) +typedef char cef_char_t; +typedef cef_string_utf8_t cef_string_t; +typedef cef_string_userfree_utf8_t cef_string_userfree_t; +#define cef_string_set cef_string_utf8_set +#define cef_string_copy cef_string_utf8_copy +#define cef_string_clear cef_string_utf8_clear +#define cef_string_userfree_alloc cef_string_userfree_utf8_alloc +#define cef_string_userfree_free cef_string_userfree_utf8_free +#define cef_string_from_ascii cef_string_utf8_copy +#define cef_string_to_utf8 cef_string_utf8_copy +#define cef_string_from_utf8 cef_string_utf8_copy +#define cef_string_to_utf16 cef_string_utf8_to_utf16 +#define cef_string_from_utf16 cef_string_utf16_to_utf8 +#define cef_string_to_wide cef_string_utf8_to_wide +#define cef_string_from_wide cef_string_wide_to_utf8 +#elif defined(CEF_STRING_TYPE_UTF16) +typedef char16 cef_char_t; +typedef cef_string_userfree_utf16_t cef_string_userfree_t; +typedef cef_string_utf16_t cef_string_t; +#define cef_string_set cef_string_utf16_set +#define cef_string_copy cef_string_utf16_copy +#define cef_string_clear cef_string_utf16_clear +#define cef_string_userfree_alloc cef_string_userfree_utf16_alloc +#define cef_string_userfree_free cef_string_userfree_utf16_free +#define cef_string_from_ascii cef_string_ascii_to_utf16 +#define cef_string_to_utf8 cef_string_utf16_to_utf8 +#define cef_string_from_utf8 cef_string_utf8_to_utf16 +#define cef_string_to_utf16 cef_string_utf16_copy +#define cef_string_from_utf16 cef_string_utf16_copy +#define cef_string_to_wide cef_string_utf16_to_wide +#define cef_string_from_wide cef_string_wide_to_utf16 +#elif defined(CEF_STRING_TYPE_WIDE) +typedef wchar_t cef_char_t; +typedef cef_string_wide_t cef_string_t; +typedef cef_string_userfree_wide_t cef_string_userfree_t; +#define cef_string_set cef_string_wide_set +#define cef_string_copy cef_string_wide_copy +#define cef_string_clear cef_string_wide_clear +#define cef_string_userfree_alloc cef_string_userfree_wide_alloc +#define cef_string_userfree_free cef_string_userfree_wide_free +#define cef_string_from_ascii cef_string_ascii_to_wide +#define cef_string_to_utf8 cef_string_wide_to_utf8 +#define cef_string_from_utf8 cef_string_utf8_to_wide +#define cef_string_to_utf16 cef_string_wide_to_utf16 +#define cef_string_from_utf16 cef_string_utf16_to_wide +#define cef_string_to_wide cef_string_wide_copy +#define cef_string_from_wide cef_string_wide_copy +#else +#error Please choose a string type. +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_H_ diff --git a/cefpython/cef3/include/internal/cef_string_list.h b/cefpython/cef3/include/internal/cef_string_list.h new file mode 100644 index 00000000..52a0abf2 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string_list.h @@ -0,0 +1,88 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string maps are a set of key/value string pairs. +/// +typedef void* cef_string_list_t; + +/// +// Allocate a new string map. +/// +CEF_EXPORT cef_string_list_t cef_string_list_alloc(); + +/// +// Return the number of elements in the string list. +/// +CEF_EXPORT int cef_string_list_size(cef_string_list_t list); + +/// +// Retrieve the value at the specified zero-based string list index. Returns +// true (1) if the value was successfully retrieved. +/// +CEF_EXPORT int cef_string_list_value(cef_string_list_t list, + int index, cef_string_t* value); + +/// +// Append a new value at the end of the string list. +/// +CEF_EXPORT void cef_string_list_append(cef_string_list_t list, + const cef_string_t* value); + +/// +// Clear the string list. +/// +CEF_EXPORT void cef_string_list_clear(cef_string_list_t list); + +/// +// Free the string list. +/// +CEF_EXPORT void cef_string_list_free(cef_string_list_t list); + +/// +// Creates a copy of an existing string list. +/// +CEF_EXPORT cef_string_list_t cef_string_list_copy(cef_string_list_t list); + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_LIST_H_ diff --git a/cefpython/cef3/include/internal/cef_string_map.h b/cefpython/cef3/include/internal/cef_string_map.h new file mode 100644 index 00000000..93eea2a5 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string_map.h @@ -0,0 +1,97 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string maps are a set of key/value string pairs. +/// +typedef void* cef_string_map_t; + +/// +// Allocate a new string map. +/// +CEF_EXPORT cef_string_map_t cef_string_map_alloc(); + +/// +// Return the number of elements in the string map. +/// +CEF_EXPORT int cef_string_map_size(cef_string_map_t map); + +/// +// Return the value assigned to the specified key. +/// +CEF_EXPORT int cef_string_map_find(cef_string_map_t map, + const cef_string_t* key, + cef_string_t* value); + +/// +// Return the key at the specified zero-based string map index. +/// +CEF_EXPORT int cef_string_map_key(cef_string_map_t map, int index, + cef_string_t* key); + +/// +// Return the value at the specified zero-based string map index. +/// +CEF_EXPORT int cef_string_map_value(cef_string_map_t map, int index, + cef_string_t* value); + +/// +// Append a new key/value pair at the end of the string map. +/// +CEF_EXPORT int cef_string_map_append(cef_string_map_t map, + const cef_string_t* key, + const cef_string_t* value); + +/// +// Clear the string map. +/// +CEF_EXPORT void cef_string_map_clear(cef_string_map_t map); + +/// +// Free the string map. +/// +CEF_EXPORT void cef_string_map_free(cef_string_map_t map); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_MAP_H_ diff --git a/cefpython/cef3/include/internal/cef_string_multimap.h b/cefpython/cef3/include/internal/cef_string_multimap.h new file mode 100644 index 00000000..cd390424 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string_multimap.h @@ -0,0 +1,105 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ +#pragma once + +#include "include/internal/cef_export.h" +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// CEF string multimaps are a set of key/value string pairs. +// More than one value can be assigned to a single key. +/// +typedef void* cef_string_multimap_t; + +/// +// Allocate a new string multimap. +/// +CEF_EXPORT cef_string_multimap_t cef_string_multimap_alloc(); + +/// +// Return the number of elements in the string multimap. +/// +CEF_EXPORT int cef_string_multimap_size(cef_string_multimap_t map); + +/// +// Return the number of values with the specified key. +/// +CEF_EXPORT int cef_string_multimap_find_count(cef_string_multimap_t map, + const cef_string_t* key); + +/// +// Return the value_index-th value with the specified key. +/// +CEF_EXPORT int cef_string_multimap_enumerate(cef_string_multimap_t map, + const cef_string_t* key, + int value_index, + cef_string_t* value); + +/// +// Return the key at the specified zero-based string multimap index. +/// +CEF_EXPORT int cef_string_multimap_key(cef_string_multimap_t map, int index, + cef_string_t* key); + +/// +// Return the value at the specified zero-based string multimap index. +/// +CEF_EXPORT int cef_string_multimap_value(cef_string_multimap_t map, int index, + cef_string_t* value); + +/// +// Append a new key/value pair at the end of the string multimap. +/// +CEF_EXPORT int cef_string_multimap_append(cef_string_multimap_t map, + const cef_string_t* key, + const cef_string_t* value); + +/// +// Clear the string multimap. +/// +CEF_EXPORT void cef_string_multimap_clear(cef_string_multimap_t map); + +/// +// Free the string multimap. +/// +CEF_EXPORT void cef_string_multimap_free(cef_string_multimap_t map); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_MULTIMAP_H_ diff --git a/cefpython/cef3/include/internal/cef_string_types.h b/cefpython/cef3/include/internal/cef_string_types.h new file mode 100644 index 00000000..7ab6671c --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string_types.h @@ -0,0 +1,204 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ +#pragma once + +// CEF provides functions for converting between UTF-8, -16 and -32 strings. +// CEF string types are safe for reading from multiple threads but not for +// modification. It is the user's responsibility to provide synchronization if +// modifying CEF strings from multiple threads. + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/internal/cef_build.h" +#include "include/internal/cef_export.h" +#include + +// CEF character type definitions. wchar_t is 2 bytes on Windows and 4 bytes on +// most other platforms. + +#if defined(OS_WIN) +typedef wchar_t char16; +#else // !OS_WIN +typedef unsigned short char16; // NOLINT (runtime/int) +#ifndef WCHAR_T_IS_UTF32 +#define WCHAR_T_IS_UTF32 +#endif // WCHAR_T_IS_UTF32 +#endif // !OS_WIN + + +// CEF string type definitions. Whomever allocates |str| is responsible for +// providing an appropriate |dtor| implementation that will free the string in +// the same memory space. When reusing an existing string structure make sure +// to call |dtor| for the old value before assigning new |str| and |dtor| +// values. Static strings will have a NULL |dtor| value. Using the below +// functions if you want this managed for you. + +typedef struct _cef_string_wide_t { + wchar_t* str; + size_t length; + void (*dtor)(wchar_t* str); +} cef_string_wide_t; + +typedef struct _cef_string_utf8_t { + char* str; + size_t length; + void (*dtor)(char* str); +} cef_string_utf8_t; + +typedef struct _cef_string_utf16_t { + char16* str; + size_t length; + void (*dtor)(char16* str); +} cef_string_utf16_t; + + +/// +// These functions set string values. If |copy| is true (1) the value will be +// copied instead of referenced. It is up to the user to properly manage +// the lifespan of references. +/// + +CEF_EXPORT int cef_string_wide_set(const wchar_t* src, size_t src_len, + cef_string_wide_t* output, int copy); +CEF_EXPORT int cef_string_utf8_set(const char* src, size_t src_len, + cef_string_utf8_t* output, int copy); +CEF_EXPORT int cef_string_utf16_set(const char16* src, size_t src_len, + cef_string_utf16_t* output, int copy); + + +/// +// Convenience macros for copying values. +/// + +#define cef_string_wide_copy(src, src_len, output) \ + cef_string_wide_set(src, src_len, output, true) +#define cef_string_utf8_copy(src, src_len, output) \ + cef_string_utf8_set(src, src_len, output, true) +#define cef_string_utf16_copy(src, src_len, output) \ + cef_string_utf16_set(src, src_len, output, true) + + +/// +// These functions clear string values. The structure itself is not freed. +/// + +CEF_EXPORT void cef_string_wide_clear(cef_string_wide_t* str); +CEF_EXPORT void cef_string_utf8_clear(cef_string_utf8_t* str); +CEF_EXPORT void cef_string_utf16_clear(cef_string_utf16_t* str); + + +/// +// These functions compare two string values with the same results as strcmp(). +/// + +CEF_EXPORT int cef_string_wide_cmp(const cef_string_wide_t* str1, + const cef_string_wide_t* str2); +CEF_EXPORT int cef_string_utf8_cmp(const cef_string_utf8_t* str1, + const cef_string_utf8_t* str2); +CEF_EXPORT int cef_string_utf16_cmp(const cef_string_utf16_t* str1, + const cef_string_utf16_t* str2); + + +/// +// These functions convert between UTF-8, -16, and -32 strings. They are +// potentially slow so unnecessary conversions should be avoided. The best +// possible result will always be written to |output| with the boolean return +// value indicating whether the conversion is 100% valid. +/// + +CEF_EXPORT int cef_string_wide_to_utf8(const wchar_t* src, size_t src_len, + cef_string_utf8_t* output); +CEF_EXPORT int cef_string_utf8_to_wide(const char* src, size_t src_len, + cef_string_wide_t* output); + +CEF_EXPORT int cef_string_wide_to_utf16(const wchar_t* src, size_t src_len, + cef_string_utf16_t* output); +CEF_EXPORT int cef_string_utf16_to_wide(const char16* src, size_t src_len, + cef_string_wide_t* output); + +CEF_EXPORT int cef_string_utf8_to_utf16(const char* src, size_t src_len, + cef_string_utf16_t* output); +CEF_EXPORT int cef_string_utf16_to_utf8(const char16* src, size_t src_len, + cef_string_utf8_t* output); + + +/// +// These functions convert an ASCII string, typically a hardcoded constant, to a +// Wide/UTF16 string. Use instead of the UTF8 conversion routines if you know +// the string is ASCII. +/// + +CEF_EXPORT int cef_string_ascii_to_wide(const char* src, size_t src_len, + cef_string_wide_t* output); +CEF_EXPORT int cef_string_ascii_to_utf16(const char* src, size_t src_len, + cef_string_utf16_t* output); + + + +/// +// It is sometimes necessary for the system to allocate string structures with +// the expectation that the user will free them. The userfree types act as a +// hint that the user is responsible for freeing the structure. +/// + +typedef cef_string_wide_t* cef_string_userfree_wide_t; +typedef cef_string_utf8_t* cef_string_userfree_utf8_t; +typedef cef_string_utf16_t* cef_string_userfree_utf16_t; + + +/// +// These functions allocate a new string structure. They must be freed by +// calling the associated free function. +/// + +CEF_EXPORT cef_string_userfree_wide_t cef_string_userfree_wide_alloc(); +CEF_EXPORT cef_string_userfree_utf8_t cef_string_userfree_utf8_alloc(); +CEF_EXPORT cef_string_userfree_utf16_t cef_string_userfree_utf16_alloc(); + + +/// +// These functions free the string structure allocated by the associated +// alloc function. Any string contents will first be cleared. +/// + +CEF_EXPORT void cef_string_userfree_wide_free(cef_string_userfree_wide_t str); +CEF_EXPORT void cef_string_userfree_utf8_free(cef_string_userfree_utf8_t str); +CEF_EXPORT void cef_string_userfree_utf16_free(cef_string_userfree_utf16_t str); + + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_TYPES_H_ diff --git a/cefpython/cef3/include/internal/cef_string_wrappers.h b/cefpython/cef3/include/internal/cef_string_wrappers.h new file mode 100644 index 00000000..9611d99c --- /dev/null +++ b/cefpython/cef3/include/internal/cef_string_wrappers.h @@ -0,0 +1,724 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ +#define CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ +#pragma once + +#include +#include +#include "include/internal/cef_string_types.h" + +#ifdef BUILDING_CEF_SHARED +#include "base/strings/string16.h" +#endif + + +/// +// Traits implementation for wide character strings. +/// +struct CefStringTraitsWide { + typedef wchar_t char_type; + typedef cef_string_wide_t struct_type; + typedef cef_string_userfree_wide_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_wide_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_wide_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_wide_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_wide_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_wide_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type *s) { + return cef_string_ascii_to_wide(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type *s) { + cef_string_utf8_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_wide_to_utf8(s->str, s->length, &cstr); + std::string str; + if (cstr.length > 0) + str = std::string(cstr.str, cstr.length); + cef_string_utf8_clear(&cstr); + return str; + } + static inline bool from_string(const std::string& str, struct_type *s) { + return cef_string_utf8_to_wide(str.c_str(), str.length(), s) ? true : false; + } + static inline std::wstring to_wstring(const struct_type *s) { + return std::wstring(s->str, s->length); + } + static inline bool from_wstring(const std::wstring& str, struct_type *s) { + return cef_string_wide_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#if defined(BUILDING_CEF_SHARED) +#if defined(WCHAR_T_IS_UTF32) + static inline string16 to_string16(const struct_type *s) { + cef_string_utf16_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_wide_to_utf16(s->str, s->length, &cstr); + string16 str; + if (cstr.length > 0) + str = string16(cstr.str, cstr.length); + cef_string_utf16_clear(&cstr); + return str; + } + static inline bool from_string16(const string16& str, struct_type *s) { + return cef_string_utf16_to_wide(str.c_str(), str.length(), s) ? + true : false; + } +#else // WCHAR_T_IS_UTF32 + static inline string16 to_string16(const struct_type *s) { + return string16(s->str, s->length); + } + static inline bool from_string16(const string16& str, struct_type *s) { + return cef_string_wide_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // WCHAR_T_IS_UTF32 +#endif // BUILDING_CEF_SHARED +}; + +/// +// Traits implementation for utf8 character strings. +/// +struct CefStringTraitsUTF8 { + typedef char char_type; + typedef cef_string_utf8_t struct_type; + typedef cef_string_userfree_utf8_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_utf8_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_utf8_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_utf8_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_utf8_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_utf8_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type* s) { + return cef_string_utf8_copy(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type* s) { + return std::string(s->str, s->length); + } + static inline bool from_string(const std::string& str, struct_type* s) { + return cef_string_utf8_copy(str.c_str(), str.length(), s) ? true : false; + } + static inline std::wstring to_wstring(const struct_type* s) { + cef_string_wide_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf8_to_wide(s->str, s->length, &cstr); + std::wstring str; + if (cstr.length > 0) + str = std::wstring(cstr.str, cstr.length); + cef_string_wide_clear(&cstr); + return str; + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_wide_to_utf8(str.c_str(), str.length(), s) ? true : false; + } +#if defined(BUILDING_CEF_SHARED) + static inline string16 to_string16(const struct_type* s) { + cef_string_utf16_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf8_to_utf16(s->str, s->length, &cstr); + string16 str; + if (cstr.length > 0) + str = string16(cstr.str, cstr.length); + cef_string_utf16_clear(&cstr); + return str; + } + static inline bool from_string16(const string16& str, struct_type* s) { + return cef_string_utf16_to_utf8(str.c_str(), str.length(), s) ? + true : false; + } +#endif // BUILDING_CEF_SHARED +}; + +/// +// Traits implementation for utf16 character strings. +/// +struct CefStringTraitsUTF16 { + typedef char16 char_type; + typedef cef_string_utf16_t struct_type; + typedef cef_string_userfree_utf16_t userfree_struct_type; + + static inline void clear(struct_type *s) { cef_string_utf16_clear(s); } + static inline int set(const char_type* src, size_t src_size, + struct_type* output, int copy) { + return cef_string_utf16_set(src, src_size, output, copy); + } + static inline int compare(const struct_type* s1, const struct_type* s2) { + return cef_string_utf16_cmp(s1, s2); + } + static inline userfree_struct_type userfree_alloc() { + return cef_string_userfree_utf16_alloc(); + } + static inline void userfree_free(userfree_struct_type ufs) { + return cef_string_userfree_utf16_free(ufs); + } + + // Conversion methods. + static inline bool from_ascii(const char* str, size_t len, struct_type* s) { + return cef_string_ascii_to_utf16(str, len, s) ? true : false; + } + static inline std::string to_string(const struct_type* s) { + cef_string_utf8_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf16_to_utf8(s->str, s->length, &cstr); + std::string str; + if (cstr.length > 0) + str = std::string(cstr.str, cstr.length); + cef_string_utf8_clear(&cstr); + return str; + } + static inline bool from_string(const std::string& str, struct_type* s) { + return cef_string_utf8_to_utf16(str.c_str(), str.length(), s) ? + true : false; + } +#if defined(WCHAR_T_IS_UTF32) + static inline std::wstring to_wstring(const struct_type* s) { + cef_string_wide_t cstr; + memset(&cstr, 0, sizeof(cstr)); + cef_string_utf16_to_wide(s->str, s->length, &cstr); + std::wstring str; + if (cstr.length > 0) + str = std::wstring(cstr.str, cstr.length); + cef_string_wide_clear(&cstr); + return str; + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_wide_to_utf16(str.c_str(), str.length(), s) ? + true : false; + } +#else // WCHAR_T_IS_UTF32 + static inline std::wstring to_wstring(const struct_type* s) { + return std::wstring(s->str, s->length); + } + static inline bool from_wstring(const std::wstring& str, struct_type* s) { + return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // WCHAR_T_IS_UTF32 +#if defined(BUILDING_CEF_SHARED) + static inline string16 to_string16(const struct_type* s) { + return string16(s->str, s->length); + } + static inline bool from_string16(const string16& str, struct_type* s) { + return cef_string_utf16_set(str.c_str(), str.length(), s, true) ? + true : false; + } +#endif // BUILDING_CEF_SHARED +}; + +/// +// CEF string classes can convert between all supported string types. For +// example, the CefStringWide class uses wchar_t as the underlying character +// type and provides two approaches for converting data to/from a UTF8 string +// (std::string). +//

+// 1. Implicit conversion using the assignment operator overload. +//

+//   CefStringWide aCefString;
+//   std::string aUTF8String;
+//   aCefString = aUTF8String; // Assign std::string to CefStringWide
+//   aUTF8String = aCefString; // Assign CefStringWide to std::string
+// 
+// 2. Explicit conversion using the FromString/ToString methods. +//
+//   CefStringWide aCefString;
+//   std::string aUTF8String;
+//   aCefString.FromString(aUTF8String); // Assign std::string to CefStringWide
+//   aUTF8String = aCefString.ToString(); // Assign CefStringWide to std::string
+// 
+// Conversion will only occur if the assigned value is a different string type. +// Assigning a std::string to a CefStringUTF8, for example, will copy the data +// without performing a conversion. +//

+// CEF string classes are safe for reading from multiple threads but not for +// modification. It is the user's responsibility to provide synchronization if +// modifying CEF strings from multiple threads. +/// +template +class CefStringBase { + public: + typedef typename traits::char_type char_type; + typedef typename traits::struct_type struct_type; + typedef typename traits::userfree_struct_type userfree_struct_type; + + /// + // Default constructor. + /// + CefStringBase() : string_(NULL), owner_(false) {} + + /// + // Create a new string from an existing string. Data will always be copied. + /// + CefStringBase(const CefStringBase& str) + : string_(NULL), owner_(false) { + FromString(str.c_str(), str.length(), true); + } + + /// + // Create a new string from an existing std::string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const std::string& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromString(src); + } + CefStringBase(const char* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromString(std::string(src)); + } + + /// + // Create a new string from an existing std::wstring. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const std::wstring& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromWString(src); + } + CefStringBase(const wchar_t* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromWString(std::wstring(src)); + } + +#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) + /// + // Create a new string from an existing string16. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + CefStringBase(const string16& src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + FromString16(src); + } + CefStringBase(const char16* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (src) + FromString16(string16(src)); + } +#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 + + /// + // Create a new string from an existing character array. If |copy| is true + // this class will copy the data. Otherwise, this class will reference the + // existing data. Referenced data must exist for the lifetime of this class + // and will not be freed by this class. + /// + CefStringBase(const char_type* src, size_t src_len, bool copy) + : string_(NULL), owner_(false) { + if (src && src_len > 0) + FromString(src, src_len, copy); + } + + /// + // Create a new string referencing an existing string structure without taking + // ownership. Referenced structures must exist for the lifetime of this class + // and will not be freed by this class. + /// + CefStringBase(const struct_type* src) // NOLINT(runtime/explicit) + : string_(NULL), owner_(false) { + if (!src) + return; + // Reference the existing structure without taking ownership. + Attach(const_cast(src), false); + } + + virtual ~CefStringBase() { ClearAndFree(); } + + + // The following methods are named for compatibility with the standard library + // string template types. + + /// + // Return a read-only pointer to the string data. + /// + const char_type* c_str() const { return (string_ ? string_->str : NULL); } + + /// + // Return the length of the string data. + /// + size_t length() const { return (string_ ? string_->length : 0); } + + /// + // Return the length of the string data. + /// + inline size_t size() const { return length(); } + + /// + // Returns true if the string is empty. + /// + bool empty() const { return (string_ == NULL || string_->length == 0); } + + /// + // Compare this string to the specified string. + /// + int compare(const CefStringBase& str) const { + if (empty() && str.empty()) + return 0; + if (empty()) + return -1; + if (str.empty()) + return 1; + return traits::compare(string_, str.GetStruct()); + } + + /// + // Clear the string data. + /// + void clear() { + if (string_) + traits::clear(string_); + } + + /// + // Swap this string's contents with the specified string. + /// + void swap(CefStringBase& str) { + struct_type* tmp_string = string_; + bool tmp_owner = owner_; + string_ = str.string_; + owner_ = str.owner_; + str.string_ = tmp_string; + str.owner_ = tmp_owner; + } + + + // The following methods are unique to CEF string template types. + + /// + // Returns true if this class owns the underlying string structure. + /// + bool IsOwner() const { return owner_; } + + /// + // Returns a read-only pointer to the underlying string structure. May return + // NULL if no structure is currently allocated. + /// + const struct_type* GetStruct() const { return string_; } + + /// + // Returns a writable pointer to the underlying string structure. Will never + // return NULL. + /// + struct_type* GetWritableStruct() { + AllocIfNeeded(); + return string_; + } + + /// + // Clear the state of this class. The underlying string structure and data + // will be freed if this class owns the structure. + /// + void ClearAndFree() { + if (!string_) + return; + if (owner_) { + clear(); + delete string_; + } + string_ = NULL; + owner_ = false; + } + + /// + // Attach to the specified string structure. If |owner| is true this class + // will take ownership of the structure. + /// + void Attach(struct_type* str, bool owner) { + // Free the previous structure and data, if any. + ClearAndFree(); + + string_ = str; + owner_ = owner; + } + + /// + // Take ownership of the specified userfree structure's string data. The + // userfree structure itself will be freed. Only use this method with userfree + // structures. + /// + void AttachToUserFree(userfree_struct_type str) { + // Free the previous structure and data, if any. + ClearAndFree(); + + if (!str) + return; + + AllocIfNeeded(); + owner_ = true; + memcpy(string_, str, sizeof(struct_type)); + + // Free the |str| structure but not the data. + memset(str, 0, sizeof(struct_type)); + traits::userfree_free(str); + } + + /// + // Detach from the underlying string structure. To avoid memory leaks only use + // this method if you already hold a pointer to the underlying string + // structure. + /// + void Detach() { + string_ = NULL; + owner_ = false; + } + + /// + // Create a userfree structure and give it ownership of this class' string + // data. This class will be disassociated from the data. May return NULL if + // this string class currently contains no data. + /// + userfree_struct_type DetachToUserFree() { + if (empty()) + return NULL; + + userfree_struct_type str = traits::userfree_alloc(); + memcpy(str, string_, sizeof(struct_type)); + + // Free this class' structure but not the data. + memset(string_, 0, sizeof(struct_type)); + ClearAndFree(); + + return str; + } + + /// + // Set this string's data to the specified character array. If |copy| is true + // this class will copy the data. Otherwise, this class will reference the + // existing data. Referenced data must exist for the lifetime of this class + // and will not be freed by this class. + /// + bool FromString(const char_type* src, size_t src_len, bool copy) { + if (src == NULL || src_len == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::set(src, src_len, string_, copy) ? true : false; + } + + /// + // Set this string's data from an existing ASCII string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromASCII(const char* str) { + size_t len = str ? strlen(str) : 0; + if (len == 0) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_ascii(str, len, string_); + } + + /// + // Return this string's data as a std::string. Translation will occur if + // necessary based on the underlying string type. + /// + std::string ToString() const { + if (empty()) + return std::string(); + return traits::to_string(string_); + } + + /// + // Set this string's data from an existing std::string. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromString(const std::string& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string(str, string_); + } + + /// + // Return this string's data as a std::wstring. Translation will occur if + // necessary based on the underlying string type. + /// + std::wstring ToWString() const { + if (empty()) + return std::wstring(); + return traits::to_wstring(string_); + } + + /// + // Set this string's data from an existing std::wstring. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromWString(const std::wstring& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_wstring(str, string_); + } +#if defined(BUILDING_CEF_SHARED) + /// + // Return this string's data as a string16. Translation will occur if + // necessary based on the underlying string type. + /// + string16 ToString16() const { + if (empty()) + return string16(); + return traits::to_string16(string_); + } + + /// + // Set this string's data from an existing string16. Data will be always + // copied. Translation will occur if necessary based on the underlying string + // type. + /// + bool FromString16(const string16& str) { + if (str.empty()) { + clear(); + return true; + } + AllocIfNeeded(); + return traits::from_string16(str, string_); + } +#endif // BUILDING_CEF_SHARED + + /// + // Comparison operator overloads. + /// + bool operator<(const CefStringBase& str) const { + return (compare(str) < 0); + } + bool operator<=(const CefStringBase& str) const { + return (compare(str) <= 0); + } + bool operator>(const CefStringBase& str) const { + return (compare(str) > 0); + } + bool operator>=(const CefStringBase& str) const { + return (compare(str) >= 0); + } + bool operator==(const CefStringBase& str) const { + return (compare(str) == 0); + } + bool operator!=(const CefStringBase& str) const { + return (compare(str) != 0); + } + + /// + // Assignment operator overloads. + /// + CefStringBase& operator=(const CefStringBase& str) { + FromString(str.c_str(), str.length(), true); + return *this; + } + operator std::string() const { + return ToString(); + } + CefStringBase& operator=(const std::string& str) { + FromString(str); + return *this; + } + CefStringBase& operator=(const char* str) { + FromString(std::string(str)); + return *this; + } + operator std::wstring() const { + return ToWString(); + } + CefStringBase& operator=(const std::wstring& str) { + FromWString(str); + return *this; + } + CefStringBase& operator=(const wchar_t* str) { + FromWString(std::wstring(str)); + return *this; + } +#if (defined(BUILDING_CEF_SHARED) && defined(WCHAR_T_IS_UTF32)) + operator string16() const { + return ToString16(); + } + CefStringBase& operator=(const string16& str) { + FromString16(str); + return *this; + } + CefStringBase& operator=(const char16* str) { + FromString16(string16(str)); + return *this; + } +#endif // BUILDING_CEF_SHARED && WCHAR_T_IS_UTF32 + + private: + // Allocate the string structure if it doesn't already exist. + void AllocIfNeeded() { + if (string_ == NULL) { + string_ = new struct_type; + memset(string_, 0, sizeof(struct_type)); + owner_ = true; + } + } + + struct_type* string_; + bool owner_; +}; + + +typedef CefStringBase CefStringWide; +typedef CefStringBase CefStringUTF8; +typedef CefStringBase CefStringUTF16; + +#endif // CEF_INCLUDE_INTERNAL_CEF_STRING_WRAPPERS_H_ diff --git a/cefpython/cef3/include/internal/cef_time.h b/cefpython/cef3/include/internal/cef_time.h new file mode 100644 index 00000000..64e601fe --- /dev/null +++ b/cefpython/cef3/include/internal/cef_time.h @@ -0,0 +1,88 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TIME_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TIME_H_ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "include/internal/cef_export.h" +#include + +/// +// Time information. Values should always be in UTC. +/// +typedef struct _cef_time_t { + int year; // Four digit year "2007" + int month; // 1-based month (values 1 = January, etc.) + int day_of_week; // 0-based day of week (0 = Sunday, etc.) + int day_of_month; // 1-based day of month (1-31) + int hour; // Hour within the current day (0-23) + int minute; // Minute within the current hour (0-59) + int second; // Second within the current minute (0-59 plus leap + // seconds which may take it up to 60). + int millisecond; // Milliseconds within the current second (0-999) +} cef_time_t; + +/// +// Converts cef_time_t to/from time_t. Returns true (1) on success and false (0) +// on failure. +/// +CEF_EXPORT int cef_time_to_timet(const cef_time_t* cef_time, time_t* time); +CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time); + +/// +// Converts cef_time_t to/from a double which is the number of seconds since +// epoch (Jan 1, 1970). Webkit uses this format to represent time. A value of 0 +// means "not initialized". Returns true (1) on success and false (0) on +// failure. +/// +CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time); +CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time); + +/// +// Retrieve the current system time. +// +CEF_EXPORT int cef_time_now(cef_time_t* cef_time); + +/// +// Retrieve the delta in milliseconds between two time values. +// +CEF_EXPORT int cef_time_delta(const cef_time_t* cef_time1, + const cef_time_t* cef_time2, + long long* delta); + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_TIME_H_ diff --git a/cefpython/cef3/include/internal/cef_tuple.h b/cefpython/cef3/include/internal/cef_tuple.h new file mode 100644 index 00000000..c2cdf705 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_tuple.h @@ -0,0 +1,1088 @@ +// Copyright (c) 2006-2011 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The contents of this file are identical to base/tuple.h + +// A Tuple is a generic templatized container, similar in concept to std::pair. +// There are classes Tuple0 to Tuple6, cooresponding to the number of elements +// it contains. The convenient MakeTuple() function takes 0 to 6 arguments, +// and will construct and return the appropriate Tuple object. The functions +// DispatchToMethod and DispatchToFunction take a function pointer or instance +// and method pointer, and unpack a tuple into arguments to the call. +// +// Tuple elements are copied by value, and stored in the tuple. See the unit +// tests for more details of how/when the values are copied. +// +// Example usage: +// // These two methods of creating a Tuple are identical. +// Tuple2 tuple_a(1, "wee"); +// Tuple2 tuple_b = MakeTuple(1, "wee"); +// +// void SomeFunc(int a, const char* b) { } +// DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") +// DispatchToFunction( +// &SomeFunc, MakeTuple(10, "foo")); // SomeFunc(10, "foo") +// +// struct { void SomeMeth(int a, int b, int c) { } } foo; +// DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3)); +// // foo->SomeMeth(1, 2, 3); + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ +#pragma once + +// If base/tuple.h is included first then exclude this file. This is to +// facilitate the use of both base/bind.h and cef_runnable.h in unit tests. +#ifndef BASE_TUPLE_H__ + +#if defined(OS_CHROMEOS) +// To troubleshoot crosbug.com/7327. +#include "base/logging.h" +#endif +// Traits ---------------------------------------------------------------------- +// +// A simple traits class for tuple arguments. +// +// ValueType: the bare, nonref version of a type (same as the type for nonrefs). +// RefType: the ref version of a type (same as the type for refs). +// ParamType: what type to pass to functions (refs should not be constified). + +template +struct TupleTraits { + typedef P ValueType; + typedef P& RefType; + typedef const P& ParamType; +}; + +template +struct TupleTraits { + typedef P ValueType; + typedef P& RefType; + typedef P& ParamType; +}; + +template +struct TupleTypes { }; + +// Tuple ----------------------------------------------------------------------- +// +// This set of classes is useful for bundling 0 or more heterogeneous data types +// into a single variable. The advantage of this is that it greatly simplifies +// function objects that need to take an arbitrary number of parameters; see +// RunnableMethod and IPC::MessageWithTuple. +// +// Tuple0 is supplied to act as a 'void' type. It can be used, for example, +// when dispatching to a function that accepts no arguments (see the +// Dispatchers below). +// Tuple1 is rarely useful. One such use is when A is non-const ref that you +// want filled by the dispatchee, and the tuple is merely a container for that +// output (a "tier"). See MakeRefTuple and its usages. + +struct Tuple0 { + typedef Tuple0 ValueTuple; + typedef Tuple0 RefTuple; + typedef Tuple0 ParamTuple; +}; + +template +struct Tuple1 { + public: + typedef A TypeA; + + Tuple1() {} + explicit Tuple1(typename TupleTraits::ParamType a) : a(a) {} + + A a; +}; + +template +struct Tuple2 { + public: + typedef A TypeA; + typedef B TypeB; + + Tuple2() {} + Tuple2(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b) + : a(a), b(b) { + } + + A a; + B b; +}; + +template +struct Tuple3 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + + Tuple3() {} + Tuple3(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c) + : a(a), b(b), c(c) { + } + + A a; + B b; + C c; +}; + +template +struct Tuple4 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + + Tuple4() {} + Tuple4(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d) + : a(a), b(b), c(c), d(d) { + } + + A a; + B b; + C c; + D d; +}; + +template +struct Tuple5 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + + Tuple5() {} + Tuple5(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e) + : a(a), b(b), c(c), d(d), e(e) { + } + + A a; + B b; + C c; + D d; + E e; +}; + +template +struct Tuple6 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + + Tuple6() {} + Tuple6(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f) + : a(a), b(b), c(c), d(d), e(e), f(f) { + } + + A a; + B b; + C c; + D d; + E e; + F f; +}; + +template +struct Tuple7 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + typedef G TypeG; + + Tuple7() {} + Tuple7(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::ParamType g) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g) { + } + + A a; + B b; + C c; + D d; + E e; + F f; + G g; +}; + +template +struct Tuple8 { + public: + typedef A TypeA; + typedef B TypeB; + typedef C TypeC; + typedef D TypeD; + typedef E TypeE; + typedef F TypeF; + typedef G TypeG; + typedef H TypeH; + + Tuple8() {} + Tuple8(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::ParamType g, + typename TupleTraits::ParamType h) + : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) { + } + + A a; + B b; + C c; + D d; + E e; + F f; + G g; + H h; +}; + +// Tuple types ---------------------------------------------------------------- +// +// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the +// definitions of class types the tuple takes as parameters. + +template <> +struct TupleTypes< Tuple0 > { + typedef Tuple0 ValueTuple; + typedef Tuple0 RefTuple; + typedef Tuple0 ParamTuple; +}; + +template +struct TupleTypes< Tuple1 > { + typedef Tuple1::ValueType> ValueTuple; + typedef Tuple1::RefType> RefTuple; + typedef Tuple1::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple2 > { + typedef Tuple2::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple2::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple2::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple3 > { + typedef Tuple3::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple3::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple3::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple4 > { + typedef Tuple4::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple4::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple4::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple5 > { + typedef Tuple5::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple5::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple5::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple6 > { + typedef Tuple6::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple6::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple6::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple7 > { + typedef Tuple7::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple7::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple7::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +template +struct TupleTypes< Tuple8 > { + typedef Tuple8::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType, + typename TupleTraits::ValueType> ValueTuple; +typedef Tuple8::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType, + typename TupleTraits::RefType> RefTuple; + typedef Tuple8::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType, + typename TupleTraits::ParamType> ParamTuple; +}; + +// Tuple creators ------------------------------------------------------------- +// +// Helper functions for constructing tuples while inferring the template +// argument types. + +inline Tuple0 MakeTuple() { + return Tuple0(); +} + +template +inline Tuple1 MakeTuple(const A& a) { + return Tuple1(a); +} + +template +inline Tuple2 MakeTuple(const A& a, const B& b) { + return Tuple2(a, b); +} + +template +inline Tuple3 MakeTuple(const A& a, const B& b, const C& c) { + return Tuple3(a, b, c); +} + +template +inline Tuple4 MakeTuple(const A& a, const B& b, const C& c, + const D& d) { + return Tuple4(a, b, c, d); +} + +template +inline Tuple5 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e) { + return Tuple5(a, b, c, d, e); +} + +template +inline Tuple6 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e, const F& f) { + return Tuple6(a, b, c, d, e, f); +} + +template +inline Tuple7 MakeTuple(const A& a, const B& b, const C& c, + const D& d, const E& e, const F& f, + const G& g) { + return Tuple7(a, b, c, d, e, f, g); +} + +template +inline Tuple8 MakeTuple(const A& a, const B& b, + const C& c, const D& d, + const E& e, const F& f, + const G& g, const H& h) { + return Tuple8(a, b, c, d, e, f, g, h); +} + +// The following set of helpers make what Boost refers to as "Tiers" - a tuple +// of references. + +template +inline Tuple1 MakeRefTuple(A& a) { + return Tuple1(a); +} + +template +inline Tuple2 MakeRefTuple(A& a, B& b) { + return Tuple2(a, b); +} + +template +inline Tuple3 MakeRefTuple(A& a, B& b, C& c) { + return Tuple3(a, b, c); +} + +template +inline Tuple4 MakeRefTuple(A& a, B& b, C& c, D& d) { + return Tuple4(a, b, c, d); +} + +template +inline Tuple5 MakeRefTuple(A& a, B& b, C& c, D& d, E& e) { + return Tuple5(a, b, c, d, e); +} + +template +inline Tuple6 MakeRefTuple(A& a, B& b, C& c, D& d, E& e, + F& f) { + return Tuple6(a, b, c, d, e, f); +} + +template +inline Tuple7 MakeRefTuple(A& a, B& b, C& c, D& d, + E& e, F& f, G& g) { + return Tuple7(a, b, c, d, e, f, g); +} + +template +inline Tuple8 MakeRefTuple(A& a, B& b, C& c, + D& d, E& e, F& f, + G& g, H& h) { + return Tuple8(a, b, c, d, e, f, g, h); +} + +// Dispatchers ---------------------------------------------------------------- +// +// Helper functions that call the given method on an object, with the unpacked +// tuple arguments. Notice that they all have the same number of arguments, +// so you need only write: +// DispatchToMethod(object, &Object::method, args); +// This is very useful for templated dispatchers, since they don't need to know +// what type |args| is. + +// Non-Static Dispatchers with no out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) { + (obj->*method)(); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) { + (obj->*method)(arg); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1& arg) { +#if defined(OS_CHROMEOS) + // To troubleshoot crosbug.com/7327. + CHECK(obj); + CHECK(&arg); + CHECK(method); +#endif + (obj->*method)(arg.a); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple2& arg) { + (obj->*method)(arg.a, arg.b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& arg) { + (obj->*method)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple7& arg) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g); +} + +// Static Dispatchers with no out params. + +template +inline void DispatchToFunction(Function function, const Tuple0& arg) { + (*function)(); +} + +template +inline void DispatchToFunction(Function function, const A& arg) { + (*function)(arg); +} + +template +inline void DispatchToFunction(Function function, const Tuple1& arg) { + (*function)(arg.a); +} + +template +inline void DispatchToFunction(Function function, const Tuple2& arg) { + (*function)(arg.a, arg.b); +} + +template +inline void DispatchToFunction(Function function, const Tuple3& arg) { + (*function)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToFunction(Function function, + const Tuple4& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToFunction(Function function, + const Tuple5& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToFunction(Function function, + const Tuple6& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +template +inline void DispatchToFunction(Function function, + const Tuple7& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g); +} + +template +inline void DispatchToFunction(Function function, + const Tuple8& arg) { + (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g, arg.h); +} + +// Dispatchers with 0 out param (as a Tuple0). + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple0& arg, Tuple0*) { + (obj->*method)(); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) { + (obj->*method)(arg); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple1& arg, Tuple0*) { + (obj->*method)(arg.a); +} + +template +inline void DispatchToMethod(ObjT* obj, + Method method, + const Tuple2& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& arg, Tuple0*) { + (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f); +} + +// Dispatchers with 1 out param. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple1* out) { + (obj->*method)(&out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple1* out) { + (obj->*method)(in, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple1* out) { + (obj->*method)(in.a, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple1* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a); +} + +// Dispatchers with 2 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple2* out) { + (obj->*method)(&out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple2* out) { + (obj->*method)(in, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple2* out) { + (obj->*method)(in.a, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple2* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b); +} + +// Dispatchers with 3 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple3* out) { + (obj->*method)(&out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple3* out) { + (obj->*method)(in, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple3* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b, &out->c); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple3* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b, &out->c); +} + +// Dispatchers with 4 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple4* out) { + (obj->*method)(&out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple4* out) { + (obj->*method)(in, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple4* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, + &out->a, &out->b, &out->c, &out->d); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple4* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, + &out->a, &out->b, &out->c, &out->d); +} + +// Dispatchers with 5 out params. + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple0& in, + Tuple5* out) { + (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const InA& in, + Tuple5* out) { + (obj->*method)(in, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple1& in, + Tuple5* out) { + (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple2& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple3& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple4& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d, + &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple5& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, + &out->a, &out->b, &out->c, &out->d, &out->e); +} + +template +inline void DispatchToMethod(ObjT* obj, Method method, + const Tuple6& in, + Tuple5* out) { + (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, + &out->a, &out->b, &out->c, &out->d, &out->e); +} + +#endif // BASE_TUPLE_H__ + +#endif // CEF_INCLUDE_INTERNAL_CEF_TUPLE_H_ diff --git a/cefpython/cef3/include/internal/cef_types.h b/cefpython/cef3/include/internal/cef_types.h new file mode 100644 index 00000000..5eb1ee0e --- /dev/null +++ b/cefpython/cef3/include/internal/cef_types.h @@ -0,0 +1,1740 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ +#pragma once + +#include "include/internal/cef_build.h" +#include "include/internal/cef_string.h" +#include "include/internal/cef_string_list.h" +#include "include/internal/cef_time.h" + +// Bring in platform-specific definitions. +#if defined(OS_WIN) +#include "include/internal/cef_types_win.h" +#elif defined(OS_MACOSX) +#include "include/internal/cef_types_mac.h" +#elif defined(OS_LINUX) +#include "include/internal/cef_types_linux.h" +#endif + +#include // For size_t + +// The NSPR system headers define 64-bit as |long| when possible, except on +// Mac OS X. In order to not have typedef mismatches, we do the same on LP64. +// +// On Mac OS X, |long long| is used for 64-bit types for compatibility with +// format macros even in the LP64 model. +#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +typedef long int64; // NOLINT(runtime/int) +typedef unsigned long uint64; // NOLINT(runtime/int) +#else +typedef long long int64; // NOLINT(runtime/int) +typedef unsigned long long uint64; // NOLINT(runtime/int) +#endif + +// TODO: Remove these type guards. These are to avoid conflicts with +// obsolete/protypes.h in the Gecko SDK. +#ifndef _INT32 +#define _INT32 +typedef int int32; +#endif + +// TODO: Remove these type guards. These are to avoid conflicts with +// obsolete/protypes.h in the Gecko SDK. +#ifndef _UINT32 +#define _UINT32 +typedef unsigned int uint32; +#endif + +// UTF-16 character type. +#ifndef char16 +#if defined(WIN32) +typedef wchar_t char16; +#else +typedef unsigned short char16; +#endif +#endif + +// 32-bit ARGB color value, not premultiplied. The color components are always +// in a known order. Equivalent to the SkColor type. +typedef uint32 cef_color_t; + +// Return the alpha byte from a cef_color_t value. +#define CefColorGetA(color) (((color) >> 24) & 0xFF) +// Return the red byte from a cef_color_t value. +#define CefColorGetR(color) (((color) >> 16) & 0xFF) +// Return the green byte from a cef_color_t value. +#define CefColorGetG(color) (((color) >> 8) & 0xFF) +// Return the blue byte from a cef_color_t value. +#define CefColorGetB(color) (((color) >> 0) & 0xFF) + +// Return an cef_color_t value with the specified byte component values. +#define CefColorSetARGB(a, r, g, b) \ + static_cast( \ + (static_cast(a) << 24) | \ + (static_cast(r) << 16) | \ + (static_cast(g) << 8) | \ + (static_cast(b) << 0)) + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// Log severity levels. +/// +enum cef_log_severity_t { + /// + // Default logging (currently INFO logging). + /// + LOGSEVERITY_DEFAULT, + + /// + // Verbose logging. + /// + LOGSEVERITY_VERBOSE, + + /// + // INFO logging. + /// + LOGSEVERITY_INFO, + + /// + // WARNING logging. + /// + LOGSEVERITY_WARNING, + + /// + // ERROR logging. + /// + LOGSEVERITY_ERROR, + + /// + // ERROR_REPORT logging. + /// + LOGSEVERITY_ERROR_REPORT, + + /// + // Completely disable logging. + /// + LOGSEVERITY_DISABLE = 99 +}; + +/// +// Represents the state of a setting. +/// +enum cef_state_t { + /// + // Use the default state for the setting. + /// + STATE_DEFAULT = 0, + + /// + // Enable or allow the setting. + /// + STATE_ENABLED, + + /// + // Disable or disallow the setting. + /// + STATE_DISABLED, +}; + +/// +// Initialization settings. Specify NULL or 0 to get the recommended default +// values. Many of these and other settings can also configured using command- +// line switches. +/// +typedef struct _cef_settings_t { + /// + // Size of this structure. + /// + size_t size; + + /// + // Set to true (1) to use a single process for the browser and renderer. This + // run mode is not officially supported by Chromium and is less stable than + // the multi-process default. Also configurable using the "single-process" + // command-line switch. + /// + bool single_process; + + /// + // The path to a separate executable that will be launched for sub-processes. + // By default the browser process executable is used. See the comments on + // CefExecuteProcess() for details. Also configurable using the + // "browser-subprocess-path" command-line switch. + /// + cef_string_t browser_subprocess_path; + + /// + // Set to true (1) to have the browser process message loop run in a separate + // thread. If false (0) than the CefDoMessageLoopWork() function must be + // called from your application message loop. + /// + bool multi_threaded_message_loop; + + /// + // Set to true (1) to disable configuration of browser process features using + // standard CEF and Chromium command-line arguments. Configuration can still + // be specified using CEF data structures or via the + // CefApp::OnBeforeCommandLineProcessing() method. + /// + bool command_line_args_disabled; + + /// + // The location where cache data will be stored on disk. If empty an in-memory + // cache will be used for some features and a temporary disk cache for others. + // HTML5 databases such as localStorage will only persist across sessions if a + // cache path is specified. + /// + cef_string_t cache_path; + + /// + // To persist session cookies (cookies without an expiry date or validity + // interval) by default when using the global cookie manager set this value to + // true. Session cookies are generally intended to be transient and most Web + // browsers do not persist them. A |cache_path| value must also be specified to + // enable this feature. Also configurable using the "persist-session-cookies" + // command-line switch. + /// + bool persist_session_cookies; + + /// + // Value that will be returned as the User-Agent HTTP header. If empty the + // default User-Agent string will be used. Also configurable using the + // "user-agent" command-line switch. + /// + cef_string_t user_agent; + + /// + // Value that will be inserted as the product portion of the default + // User-Agent string. If empty the Chromium product version will be used. If + // |userAgent| is specified this value will be ignored. Also configurable + // using the "product-version" command-line switch. + /// + cef_string_t product_version; + + /// + // The locale string that will be passed to WebKit. If empty the default + // locale of "en-US" will be used. This value is ignored on Linux where locale + // is determined using environment variable parsing with the precedence order: + // LANGUAGE, LC_ALL, LC_MESSAGES and LANG. Also configurable using the "lang" + // command-line switch. + /// + cef_string_t locale; + + /// + // The directory and file name to use for the debug log. If empty, the + // default name of "debug.log" will be used and the file will be written + // to the application directory. Also configurable using the "log-file" + // command-line switch. + /// + cef_string_t log_file; + + /// + // The log severity. Only messages of this severity level or higher will be + // logged. Also configurable using the "log-severity" command-line switch with + // a value of "verbose", "info", "warning", "error", "error-report" or + // "disable". + /// + cef_log_severity_t log_severity; + + /// + // Enable DCHECK in release mode to ease debugging. Also configurable using the + // "enable-release-dcheck" command-line switch. + /// + bool release_dcheck_enabled; + + /// + // Custom flags that will be used when initializing the V8 JavaScript engine. + // The consequences of using custom flags may not be well tested. Also + // configurable using the "js-flags" command-line switch. + /// + cef_string_t javascript_flags; + + /// + // The fully qualified path for the resources directory. If this value is + // empty the cef.pak and/or devtools_resources.pak files must be located in + // the module directory on Windows/Linux or the app bundle Resources directory + // on Mac OS X. Also configurable using the "resources-dir-path" command-line + // switch. + /// + cef_string_t resources_dir_path; + + /// + // The fully qualified path for the locales directory. If this value is empty + // the locales directory must be located in the module directory. This value + // is ignored on Mac OS X where pack files are always loaded from the app + // bundle Resources directory. Also configurable using the "locales-dir-path" + // command-line switch. + /// + cef_string_t locales_dir_path; + + /// + // Set to true (1) to disable loading of pack files for resources and locales. + // A resource bundle handler must be provided for the browser and render + // processes via CefApp::GetResourceBundleHandler() if loading of pack files + // is disabled. Also configurable using the "disable-pack-loading" command- + // line switch. + /// + bool pack_loading_disabled; + + /// + // Set to a value between 1024 and 65535 to enable remote debugging on the + // specified port. For example, if 8080 is specified the remote debugging URL + // will be http://localhost:8080. CEF can be remotely debugged from any CEF or + // Chrome browser window. Also configurable using the "remote-debugging-port" + // command-line switch. + /// + int remote_debugging_port; + + /// + // The number of stack trace frames to capture for uncaught exceptions. + // Specify a positive value to enable the CefV8ContextHandler:: + // OnUncaughtException() callback. Specify 0 (default value) and + // OnUncaughtException() will not be called. Also configurable using the + // "uncaught-exception-stack-size" command-line switch. + /// + int uncaught_exception_stack_size; + + /// + // By default CEF V8 references will be invalidated (the IsValid() method will + // return false) after the owning context has been released. This reduces the + // need for external record keeping and avoids crashes due to the use of V8 + // references after the associated context has been released. + // + // CEF currently offers two context safety implementations with different + // performance characteristics. The default implementation (value of 0) uses a + // map of hash values and should provide better performance in situations with + // a small number contexts. The alternate implementation (value of 1) uses a + // hidden value attached to each context and should provide better performance + // in situations with a large number of contexts. + // + // If you need better performance in the creation of V8 references and you + // plan to manually track context lifespan you can disable context safety by + // specifying a value of -1. + // + // Also configurable using the "context-safety-implementation" command-line + // switch. + /// + int context_safety_implementation; + + /// + // Set to true (1) to ignore errors related to invalid SSL certificates. + // Enabling this setting can lead to potential security vulnerabilities like + // "man in the middle" attacks. Applications that load content from the + // internet should not enable this setting. Also configurable using the + // "ignore-certificate-errors" command-line switch. + /// + bool ignore_certificate_errors; + + /// + // Used on Mac OS X to specify the background color for hardware accelerated + // content. + /// + cef_color_t background_color; +} cef_settings_t; + +/// +// Browser initialization settings. Specify NULL or 0 to get the recommended +// default values. The consequences of using custom values may not be well +// tested. Many of these and other settings can also configured using command- +// line switches. +/// +typedef struct _cef_browser_settings_t { + /// + // Size of this structure. + /// + size_t size; + + // The below values map to WebPreferences settings. + + /// + // Font settings. + /// + cef_string_t standard_font_family; + cef_string_t fixed_font_family; + cef_string_t serif_font_family; + cef_string_t sans_serif_font_family; + cef_string_t cursive_font_family; + cef_string_t fantasy_font_family; + int default_font_size; + int default_fixed_font_size; + int minimum_font_size; + int minimum_logical_font_size; + + /// + // Default encoding for Web content. If empty "ISO-8859-1" will be used. Also + // configurable using the "default-encoding" command-line switch. + /// + cef_string_t default_encoding; + + /// + // Location of the user style sheet that will be used for all pages. This must + // be a data URL of the form "data:text/css;charset=utf-8;base64,csscontent" + // where "csscontent" is the base64 encoded contents of the CSS file. Also + // configurable using the "user-style-sheet-location" command-line switch. + /// + cef_string_t user_style_sheet_location; + + /// + // Controls the loading of fonts from remote sources. Also configurable using + // the "disable-remote-fonts" command-line switch. + /// + cef_state_t remote_fonts; + + /// + // Controls whether JavaScript can be executed. Also configurable using the + // "disable-javascript" command-line switch. + /// + cef_state_t javascript; + + /// + // Controls whether JavaScript can be used for opening windows. Also + // configurable using the "disable-javascript-open-windows" command-line + // switch. + /// + cef_state_t javascript_open_windows; + + /// + // Controls whether JavaScript can be used to close windows that were not + // opened via JavaScript. JavaScript can still be used to close windows that + // were opened via JavaScript. Also configurable using the + // "disable-javascript-close-windows" command-line switch. + /// + cef_state_t javascript_close_windows; + + /// + // Controls whether JavaScript can access the clipboard. Also configurable + // using the "disable-javascript-access-clipboard" command-line switch. + /// + cef_state_t javascript_access_clipboard; + + /// + // Controls whether DOM pasting is supported in the editor via + // execCommand("paste"). The |javascript_access_clipboard| setting must also + // be enabled. Also configurable using the "disable-javascript-dom-paste" + // command-line switch. + /// + cef_state_t javascript_dom_paste; + + /// + // Controls whether the caret position will be drawn. Also configurable using + // the "enable-caret-browsing" command-line switch. + /// + cef_state_t caret_browsing; + + /// + // Controls whether the Java plugin will be loaded. Also configurable using + // the "disable-java" command-line switch. + /// + cef_state_t java; + + /// + // Controls whether any plugins will be loaded. Also configurable using the + // "disable-plugins" command-line switch. + /// + cef_state_t plugins; + + /// + // Controls whether file URLs will have access to all URLs. Also configurable + // using the "allow-universal-access-from-files" command-line switch. + /// + cef_state_t universal_access_from_file_urls; + + /// + // Controls whether file URLs will have access to other file URLs. Also + // configurable using the "allow-access-from-files" command-line switch. + /// + cef_state_t file_access_from_file_urls; + + /// + // Controls whether web security restrictions (same-origin policy) will be + // enforced. Disabling this setting is not recommend as it will allow risky + // security behavior such as cross-site scripting (XSS). Also configurable + // using the "disable-web-security" command-line switch. + /// + cef_state_t web_security; + + /// + // Controls whether image URLs will be loaded from the network. A cached image + // will still be rendered if requested. Also configurable using the + // "disable-image-loading" command-line switch. + /// + cef_state_t image_loading; + + /// + // Controls whether standalone images will be shrunk to fit the page. Also + // configurable using the "image-shrink-standalone-to-fit" command-line + // switch. + /// + cef_state_t image_shrink_standalone_to_fit; + + /// + // Controls whether text areas can be resized. Also configurable using the + // "disable-text-area-resize" command-line switch. + /// + cef_state_t text_area_resize; + + /// + // Controls whether the tab key can advance focus to links. Also configurable + // using the "disable-tab-to-links" command-line switch. + /// + cef_state_t tab_to_links; + + /// + // Controls whether style sheets can be used. Also configurable using the + // "disable-author-and-user-styles" command-line switch. + /// + cef_state_t author_and_user_styles; + + /// + // Controls whether local storage can be used. Also configurable using the + // "disable-local-storage" command-line switch. + /// + cef_state_t local_storage; + + /// + // Controls whether databases can be used. Also configurable using the + // "disable-databases" command-line switch. + /// + cef_state_t databases; + + /// + // Controls whether the application cache can be used. Also configurable using + // the "disable-application-cache" command-line switch. + /// + cef_state_t application_cache; + + /// + // Controls whether WebGL can be used. Note that WebGL requires hardware + // support and may not work on all systems even when enabled. Also + // configurable using the "disable-webgl" command-line switch. + /// + cef_state_t webgl; + + /// + // Controls whether content that depends on accelerated compositing can be + // used. Note that accelerated compositing requires hardware support and may + // not work on all systems even when enabled. Also configurable using the + // "disable-accelerated-compositing" command-line switch. + /// + cef_state_t accelerated_compositing; +} cef_browser_settings_t; + +/// +// URL component parts. +/// +typedef struct _cef_urlparts_t { + /// + // The complete URL specification. + /// + cef_string_t spec; + + /// + // Scheme component not including the colon (e.g., "http"). + /// + cef_string_t scheme; + + /// + // User name component. + /// + cef_string_t username; + + /// + // Password component. + /// + cef_string_t password; + + /// + // Host component. This may be a hostname, an IPv4 address or an IPv6 literal + // surrounded by square brackets (e.g., "[2001:db8::1]"). + /// + cef_string_t host; + + /// + // Port number component. + /// + cef_string_t port; + + /// + // Path component including the first slash following the host. + /// + cef_string_t path; + + /// + // Query string component (i.e., everything following the '?'). + /// + cef_string_t query; +} cef_urlparts_t; + +/// +// Cookie information. +/// +typedef struct _cef_cookie_t { + /// + // The cookie name. + /// + cef_string_t name; + + /// + // The cookie value. + /// + cef_string_t value; + + /// + // If |domain| is empty a host cookie will be created instead of a domain + // cookie. Domain cookies are stored with a leading "." and are visible to + // sub-domains whereas host cookies are not. + /// + cef_string_t domain; + + /// + // If |path| is non-empty only URLs at or below the path will get the cookie + // value. + /// + cef_string_t path; + + /// + // If |secure| is true the cookie will only be sent for HTTPS requests. + /// + bool secure; + + /// + // If |httponly| is true the cookie will only be sent for HTTP requests. + /// + bool httponly; + + /// + // The cookie creation date. This is automatically populated by the system on + // cookie creation. + /// + cef_time_t creation; + + /// + // The cookie last access date. This is automatically populated by the system + // on access. + /// + cef_time_t last_access; + + /// + // The cookie expiration date is only valid if |has_expires| is true. + /// + bool has_expires; + cef_time_t expires; +} cef_cookie_t; + +/// +// Process termination status values. +/// +enum cef_termination_status_t { + /// + // Non-zero exit status. + /// + TS_ABNORMAL_TERMINATION, + + /// + // SIGKILL or task manager kill. + /// + TS_PROCESS_WAS_KILLED, + + /// + // Segmentation fault. + /// + TS_PROCESS_CRASHED, +}; + +/// +// Path key values. +/// +enum cef_path_key_t { + /// + // Current directory. + /// + PK_DIR_CURRENT, + + /// + // Directory containing PK_FILE_EXE. + /// + PK_DIR_EXE, + + /// + // Directory containing PK_FILE_MODULE. + /// + PK_DIR_MODULE, + + /// + // Temporary directory. + /// + PK_DIR_TEMP, + + /// + // Path and filename of the current executable. + /// + PK_FILE_EXE, + + /// + // Path and filename of the module containing the CEF code (usually the libcef + // module). + /// + PK_FILE_MODULE, +}; + +/// +// Storage types. +/// +enum cef_storage_type_t { + ST_LOCALSTORAGE = 0, + ST_SESSIONSTORAGE, +}; + +/// +// Supported error code values. See net\base\net_error_list.h for complete +// descriptions of the error codes. +/// +enum cef_errorcode_t { + ERR_NONE = 0, + ERR_FAILED = -2, + ERR_ABORTED = -3, + ERR_INVALID_ARGUMENT = -4, + ERR_INVALID_HANDLE = -5, + ERR_FILE_NOT_FOUND = -6, + ERR_TIMED_OUT = -7, + ERR_FILE_TOO_BIG = -8, + ERR_UNEXPECTED = -9, + ERR_ACCESS_DENIED = -10, + ERR_NOT_IMPLEMENTED = -11, + ERR_CONNECTION_CLOSED = -100, + ERR_CONNECTION_RESET = -101, + ERR_CONNECTION_REFUSED = -102, + ERR_CONNECTION_ABORTED = -103, + ERR_CONNECTION_FAILED = -104, + ERR_NAME_NOT_RESOLVED = -105, + ERR_INTERNET_DISCONNECTED = -106, + ERR_SSL_PROTOCOL_ERROR = -107, + ERR_ADDRESS_INVALID = -108, + ERR_ADDRESS_UNREACHABLE = -109, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110, + ERR_TUNNEL_CONNECTION_FAILED = -111, + ERR_NO_SSL_VERSIONS_ENABLED = -112, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113, + ERR_SSL_RENEGOTIATION_REQUESTED = -114, + ERR_CERT_COMMON_NAME_INVALID = -200, + ERR_CERT_DATE_INVALID = -201, + ERR_CERT_AUTHORITY_INVALID = -202, + ERR_CERT_CONTAINS_ERRORS = -203, + ERR_CERT_NO_REVOCATION_MECHANISM = -204, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205, + ERR_CERT_REVOKED = -206, + ERR_CERT_INVALID = -207, + ERR_CERT_END = -208, + ERR_INVALID_URL = -300, + ERR_DISALLOWED_URL_SCHEME = -301, + ERR_UNKNOWN_URL_SCHEME = -302, + ERR_TOO_MANY_REDIRECTS = -310, + ERR_UNSAFE_REDIRECT = -311, + ERR_UNSAFE_PORT = -312, + ERR_INVALID_RESPONSE = -320, + ERR_INVALID_CHUNKED_ENCODING = -321, + ERR_METHOD_NOT_SUPPORTED = -322, + ERR_UNEXPECTED_PROXY_AUTH = -323, + ERR_EMPTY_RESPONSE = -324, + ERR_RESPONSE_HEADERS_TOO_BIG = -325, + ERR_CACHE_MISS = -400, + ERR_INSECURE_RESPONSE = -501, +}; + +/// +// "Verb" of a drag-and-drop operation as negotiated between the source and +// destination. These constants match their equivalents in WebCore's +// DragActions.h and should not be renumbered. +/// +enum cef_drag_operations_mask_t { + DRAG_OPERATION_NONE = 0, + DRAG_OPERATION_COPY = 1, + DRAG_OPERATION_LINK = 2, + DRAG_OPERATION_GENERIC = 4, + DRAG_OPERATION_PRIVATE = 8, + DRAG_OPERATION_MOVE = 16, + DRAG_OPERATION_DELETE = 32, + DRAG_OPERATION_EVERY = UINT_MAX +}; + +/// +// V8 access control values. +/// +enum cef_v8_accesscontrol_t { + V8_ACCESS_CONTROL_DEFAULT = 0, + V8_ACCESS_CONTROL_ALL_CAN_READ = 1, + V8_ACCESS_CONTROL_ALL_CAN_WRITE = 1 << 1, + V8_ACCESS_CONTROL_PROHIBITS_OVERWRITING = 1 << 2 +}; + +/// +// V8 property attribute values. +/// +enum cef_v8_propertyattribute_t { + V8_PROPERTY_ATTRIBUTE_NONE = 0, // Writeable, Enumerable, + // Configurable + V8_PROPERTY_ATTRIBUTE_READONLY = 1 << 0, // Not writeable + V8_PROPERTY_ATTRIBUTE_DONTENUM = 1 << 1, // Not enumerable + V8_PROPERTY_ATTRIBUTE_DONTDELETE = 1 << 2 // Not configurable +}; + +/// +// Post data elements may represent either bytes or files. +/// +enum cef_postdataelement_type_t { + PDE_TYPE_EMPTY = 0, + PDE_TYPE_BYTES, + PDE_TYPE_FILE, +}; + +/// +// Resource type for a request. +/// +enum cef_resource_type_t { + /// + // Top level page. + /// + RT_MAIN_FRAME = 0, + + /// + // Frame or iframe. + /// + RT_SUB_FRAME, + + /// + // CSS stylesheet. + /// + RT_STYLESHEET, + + /// + // External script. + /// + RT_SCRIPT, + + /// + // Image (jpg/gif/png/etc). + /// + RT_IMAGE, + + /// + // Font. + /// + RT_FONT_RESOURCE, + + /// + // Some other subresource. This is the default type if the actual type is + // unknown. + /// + RT_SUB_RESOURCE, + + /// + // Object (or embed) tag for a plugin, or a resource that a plugin requested. + /// + RT_OBJECT, + + /// + // Media resource. + /// + RT_MEDIA, + + /// + // Main resource of a dedicated worker. + /// + RT_WORKER, + + /// + // Main resource of a shared worker. + /// + RT_SHARED_WORKER, + + /// + // Explicitly requested prefetch. + /// + RT_PREFETCH, + + /// + // Favicon. + /// + RT_FAVICON, + + /// + // XMLHttpRequest. + /// + RT_XHR, +}; + +/// +// Transition type for a request. Made up of one source value and 0 or more +// qualifiers. +/// +enum cef_transition_type_t { + /// + // Source is a link click or the JavaScript window.open function. This is + // also the default value for requests like sub-resource loads that are not + // navigations. + /// + TT_LINK = 0, + + /// + // Source is some other "explicit" navigation action such as creating a new + // browser or using the LoadURL function. This is also the default value + // for navigations where the actual type is unknown. + /// + TT_EXPLICIT = 1, + + /// + // Source is a subframe navigation. This is any content that is automatically + // loaded in a non-toplevel frame. For example, if a page consists of several + // frames containing ads, those ad URLs will have this transition type. + // The user may not even realize the content in these pages is a separate + // frame, so may not care about the URL. + /// + TT_AUTO_SUBFRAME = 3, + + /// + // Source is a subframe navigation explicitly requested by the user that will + // generate new navigation entries in the back/forward list. These are + // probably more important than frames that were automatically loaded in + // the background because the user probably cares about the fact that this + // link was loaded. + /// + TT_MANUAL_SUBFRAME = 4, + + /// + // Source is a form submission by the user. NOTE: In some situations + // submitting a form does not result in this transition type. This can happen + // if the form uses a script to submit the contents. + /// + TT_FORM_SUBMIT = 7, + + /// + // Source is a "reload" of the page via the Reload function or by re-visiting + // the same URL. NOTE: This is distinct from the concept of whether a + // particular load uses "reload semantics" (i.e. bypasses cached data). + /// + TT_RELOAD = 8, + + /// + // General mask defining the bits used for the source values. + /// + TT_SOURCE_MASK = 0xFF, + + // Qualifiers. + // Any of the core values above can be augmented by one or more qualifiers. + // These qualifiers further define the transition. + + /// + // Attempted to visit a URL but was blocked. + /// + TT_BLOCKED_FLAG = 0x00800000, + + /// + // Used the Forward or Back function to navigate among browsing history. + /// + TT_FORWARD_BACK_FLAG = 0x01000000, + + /// + // The beginning of a navigation chain. + /// + TT_CHAIN_START_FLAG = 0x10000000, + + /// + // The last transition in a redirect chain. + /// + TT_CHAIN_END_FLAG = 0x20000000, + + /// + // Redirects caused by JavaScript or a meta refresh tag on the page. + /// + TT_CLIENT_REDIRECT_FLAG = 0x40000000, + + /// + // Redirects sent from the server by HTTP headers. + /// + TT_SERVER_REDIRECT_FLAG = 0x80000000, + + /// + // Used to test whether a transition involves a redirect. + /// + TT_IS_REDIRECT_MASK = 0xC0000000, + + /// + // General mask defining the bits used for the qualifiers. + /// + TT_QUALIFIER_MASK = 0xFFFFFF00, +}; + +/// +// Flags used to customize the behavior of CefURLRequest. +/// +enum cef_urlrequest_flags_t { + /// + // Default behavior. + /// + UR_FLAG_NONE = 0, + + /// + // If set the cache will be skipped when handling the request. + /// + UR_FLAG_SKIP_CACHE = 1 << 0, + + /// + // If set user name, password, and cookies may be sent with the request. + /// + UR_FLAG_ALLOW_CACHED_CREDENTIALS = 1 << 1, + + /// + // If set cookies may be sent with the request and saved from the response. + // UR_FLAG_ALLOW_CACHED_CREDENTIALS must also be set. + /// + UR_FLAG_ALLOW_COOKIES = 1 << 2, + + /// + // If set upload progress events will be generated when a request has a body. + /// + UR_FLAG_REPORT_UPLOAD_PROGRESS = 1 << 3, + + /// + // If set load timing info will be collected for the request. + /// + UR_FLAG_REPORT_LOAD_TIMING = 1 << 4, + + /// + // If set the headers sent and received for the request will be recorded. + /// + UR_FLAG_REPORT_RAW_HEADERS = 1 << 5, + + /// + // If set the CefURLRequestClient::OnDownloadData method will not be called. + /// + UR_FLAG_NO_DOWNLOAD_DATA = 1 << 6, + + /// + // If set 5XX redirect errors will be propagated to the observer instead of + // automatically re-tried. This currently only applies for requests + // originated in the browser process. + /// + UR_FLAG_NO_RETRY_ON_5XX = 1 << 7, +}; + +/// +// Flags that represent CefURLRequest status. +/// +enum cef_urlrequest_status_t { + /// + // Unknown status. + /// + UR_UNKNOWN = 0, + + /// + // Request succeeded. + /// + UR_SUCCESS, + + /// + // An IO request is pending, and the caller will be informed when it is + // completed. + /// + UR_IO_PENDING, + + /// + // Request was canceled programatically. + /// + UR_CANCELED, + + /// + // Request failed for some reason. + /// + UR_FAILED, +}; + +/// +// Structure representing a rectangle. +/// +typedef struct _cef_rect_t { + int x; + int y; + int width; + int height; +} cef_rect_t; + +/// +// Existing process IDs. +/// +enum cef_process_id_t { + /// + // Browser process. + /// + PID_BROWSER, + /// + // Renderer process. + /// + PID_RENDERER, +}; + +/// +// Existing thread IDs. +/// +enum cef_thread_id_t { +// BROWSER PROCESS THREADS -- Only available in the browser process. + + /// + // The main thread in the browser. This will be the same as the main + // application thread if CefInitialize() is called with a + // CefSettings.multi_threaded_message_loop value of false. + /// + TID_UI, + + /// + // Used to interact with the database. + /// + TID_DB, + + /// + // Used to interact with the file system. + /// + TID_FILE, + + /// + // Used for file system operations that block user interactions. + // Responsiveness of this thread affects users. + /// + TID_FILE_USER_BLOCKING, + + /// + // Used to launch and terminate browser processes. + /// + TID_PROCESS_LAUNCHER, + + /// + // Used to handle slow HTTP cache operations. + /// + TID_CACHE, + + /// + // Used to process IPC and network messages. + /// + TID_IO, + +// RENDER PROCESS THREADS -- Only available in the render process. + + /// + // The main thread in the renderer. Used for all WebKit and V8 interaction. + /// + TID_RENDERER, +}; + +/// +// Supported value types. +/// +enum cef_value_type_t { + VTYPE_INVALID = 0, + VTYPE_NULL, + VTYPE_BOOL, + VTYPE_INT, + VTYPE_DOUBLE, + VTYPE_STRING, + VTYPE_BINARY, + VTYPE_DICTIONARY, + VTYPE_LIST, +}; + +/// +// Supported JavaScript dialog types. +/// +enum cef_jsdialog_type_t { + JSDIALOGTYPE_ALERT = 0, + JSDIALOGTYPE_CONFIRM, + JSDIALOGTYPE_PROMPT, +}; + +/// +// Screen information used when window rendering is disabled. This structure is +// passed as a parameter to CefRenderHandler::GetScreenInfo and should be filled +// in by the client. +/// +typedef struct _cef_screen_info_t { + /// + // Device scale factor. Specifies the ratio between physical and logical + // pixels. + /// + float device_scale_factor; + + /// + // The screen depth in bits per pixel. + /// + int depth; + + /// + // The bits per color component. This assumes that the colors are balanced + // equally. + /// + int depth_per_component; + + /// + // This can be true for black and white printers. + /// + bool is_monochrome; + + /// + // This is set from the rcMonitor member of MONITORINFOEX, to whit: + // "A RECT structure that specifies the display monitor rectangle, + // expressed in virtual-screen coordinates. Note that if the monitor + // is not the primary display monitor, some of the rectangle's + // coordinates may be negative values." + // + // The |rect| and |available_rect| properties are used to determine the + // available surface for rendering popup views. + /// + cef_rect_t rect; + + /// + // This is set from the rcWork member of MONITORINFOEX, to whit: + // "A RECT structure that specifies the work area rectangle of the + // display monitor that can be used by applications, expressed in + // virtual-screen coordinates. Windows uses this rectangle to + // maximize an application on the monitor. The rest of the area in + // rcMonitor contains system windows such as the task bar and side + // bars. Note that if the monitor is not the primary display monitor, + // some of the rectangle's coordinates may be negative values". + // + // The |rect| and |available_rect| properties are used to determine the + // available surface for rendering popup views. + /// + cef_rect_t available_rect; +} cef_screen_info_t; + +/// +// Supported menu IDs. Non-English translations can be provided for the +// IDS_MENU_* strings in CefResourceBundleHandler::GetLocalizedString(). +/// +enum cef_menu_id_t { + // Navigation. + MENU_ID_BACK = 100, + MENU_ID_FORWARD = 101, + MENU_ID_RELOAD = 102, + MENU_ID_RELOAD_NOCACHE = 103, + MENU_ID_STOPLOAD = 104, + + // Editing. + MENU_ID_UNDO = 110, + MENU_ID_REDO = 111, + MENU_ID_CUT = 112, + MENU_ID_COPY = 113, + MENU_ID_PASTE = 114, + MENU_ID_DELETE = 115, + MENU_ID_SELECT_ALL = 116, + + // Miscellaneous. + MENU_ID_FIND = 130, + MENU_ID_PRINT = 131, + MENU_ID_VIEW_SOURCE = 132, + + // All user-defined menu IDs should come between MENU_ID_USER_FIRST and + // MENU_ID_USER_LAST to avoid overlapping the Chromium and CEF ID ranges + // defined in the tools/gritsettings/resource_ids file. + MENU_ID_USER_FIRST = 26500, + MENU_ID_USER_LAST = 28500, +}; + +/// +// Mouse button types. +/// +enum cef_mouse_button_type_t { + MBT_LEFT = 0, + MBT_MIDDLE, + MBT_RIGHT, +}; + +/// +// Structure representing mouse event information. +/// +typedef struct _cef_mouse_event_t { + /// + // X coordinate relative to the left side of the view. + /// + int x; + + /// + // Y coordinate relative to the top side of the view. + /// + int y; + + /// + // Bit flags describing any pressed modifier keys. See + // cef_event_flags_t for values. + /// + uint32 modifiers; +} cef_mouse_event_t; + +/// +// Paint element types. +/// +enum cef_paint_element_type_t { + PET_VIEW = 0, + PET_POPUP, +}; + +/// +// Supported event bit flags. +/// +enum cef_event_flags_t { + EVENTFLAG_NONE = 0, + EVENTFLAG_CAPS_LOCK_ON = 1 << 0, + EVENTFLAG_SHIFT_DOWN = 1 << 1, + EVENTFLAG_CONTROL_DOWN = 1 << 2, + EVENTFLAG_ALT_DOWN = 1 << 3, + EVENTFLAG_LEFT_MOUSE_BUTTON = 1 << 4, + EVENTFLAG_MIDDLE_MOUSE_BUTTON = 1 << 5, + EVENTFLAG_RIGHT_MOUSE_BUTTON = 1 << 6, + // Mac OS-X command key. + EVENTFLAG_COMMAND_DOWN = 1 << 7, + EVENTFLAG_NUM_LOCK_ON = 1 << 8, + EVENTFLAG_IS_KEY_PAD = 1 << 9, + EVENTFLAG_IS_LEFT = 1 << 10, + EVENTFLAG_IS_RIGHT = 1 << 11, +}; + +/// +// Supported menu item types. +/// +enum cef_menu_item_type_t { + MENUITEMTYPE_NONE, + MENUITEMTYPE_COMMAND, + MENUITEMTYPE_CHECK, + MENUITEMTYPE_RADIO, + MENUITEMTYPE_SEPARATOR, + MENUITEMTYPE_SUBMENU, +}; + +/// +// Supported context menu type flags. +/// +enum cef_context_menu_type_flags_t { + /// + // No node is selected. + /// + CM_TYPEFLAG_NONE = 0, + /// + // The top page is selected. + /// + CM_TYPEFLAG_PAGE = 1 << 0, + /// + // A subframe page is selected. + /// + CM_TYPEFLAG_FRAME = 1 << 1, + /// + // A link is selected. + /// + CM_TYPEFLAG_LINK = 1 << 2, + /// + // A media node is selected. + /// + CM_TYPEFLAG_MEDIA = 1 << 3, + /// + // There is a textual or mixed selection that is selected. + /// + CM_TYPEFLAG_SELECTION = 1 << 4, + /// + // An editable element is selected. + /// + CM_TYPEFLAG_EDITABLE = 1 << 5, +}; + +/// +// Supported context menu media types. +/// +enum cef_context_menu_media_type_t { + /// + // No special node is in context. + /// + CM_MEDIATYPE_NONE, + /// + // An image node is selected. + /// + CM_MEDIATYPE_IMAGE, + /// + // A video node is selected. + /// + CM_MEDIATYPE_VIDEO, + /// + // An audio node is selected. + /// + CM_MEDIATYPE_AUDIO, + /// + // A file node is selected. + /// + CM_MEDIATYPE_FILE, + /// + // A plugin node is selected. + /// + CM_MEDIATYPE_PLUGIN, +}; + +/// +// Supported context menu media state bit flags. +/// +enum cef_context_menu_media_state_flags_t { + CM_MEDIAFLAG_NONE = 0, + CM_MEDIAFLAG_ERROR = 1 << 0, + CM_MEDIAFLAG_PAUSED = 1 << 1, + CM_MEDIAFLAG_MUTED = 1 << 2, + CM_MEDIAFLAG_LOOP = 1 << 3, + CM_MEDIAFLAG_CAN_SAVE = 1 << 4, + CM_MEDIAFLAG_HAS_AUDIO = 1 << 5, + CM_MEDIAFLAG_HAS_VIDEO = 1 << 6, + CM_MEDIAFLAG_CONTROL_ROOT_ELEMENT = 1 << 7, + CM_MEDIAFLAG_CAN_PRINT = 1 << 8, + CM_MEDIAFLAG_CAN_ROTATE = 1 << 9, +}; + +/// +// Supported context menu edit state bit flags. +/// +enum cef_context_menu_edit_state_flags_t { + CM_EDITFLAG_NONE = 0, + CM_EDITFLAG_CAN_UNDO = 1 << 0, + CM_EDITFLAG_CAN_REDO = 1 << 1, + CM_EDITFLAG_CAN_CUT = 1 << 2, + CM_EDITFLAG_CAN_COPY = 1 << 3, + CM_EDITFLAG_CAN_PASTE = 1 << 4, + CM_EDITFLAG_CAN_DELETE = 1 << 5, + CM_EDITFLAG_CAN_SELECT_ALL = 1 << 6, + CM_EDITFLAG_CAN_TRANSLATE = 1 << 7, +}; + +/// +// Key event types. +/// +enum cef_key_event_type_t { + KEYEVENT_RAWKEYDOWN = 0, + KEYEVENT_KEYDOWN, + KEYEVENT_KEYUP, + KEYEVENT_CHAR +}; + +/// +// Structure representing keyboard event information. +/// +typedef struct _cef_key_event_t { + /// + // The type of keyboard event. + /// + cef_key_event_type_t type; + + /// + // Bit flags describing any pressed modifier keys. See + // cef_event_flags_t for values. + /// + uint32 modifiers; + + /// + // The Windows key code for the key event. This value is used by the DOM + // specification. Sometimes it comes directly from the event (i.e. on + // Windows) and sometimes it's determined using a mapping function. See + // WebCore/platform/chromium/KeyboardCodes.h for the list of values. + /// + int windows_key_code; + + /// + // The actual key code genenerated by the platform. + /// + int native_key_code; + + /// + // Indicates whether the event is considered a "system key" event (see + // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for details). + // This value will always be false on non-Windows platforms. + /// + bool is_system_key; + + /// + // The character generated by the keystroke. + /// + char16 character; + + /// + // Same as |character| but unmodified by any concurrently-held modifiers + // (except shift). This is useful for working out shortcut keys. + /// + char16 unmodified_character; + + /// + // True if the focus is currently on an editable field on the page. This is + // useful for determining if standard key events should be intercepted. + /// + bool focus_on_editable_field; +} cef_key_event_t; + +/// +// Focus sources. +/// +enum cef_focus_source_t { + /// + // The source is explicit navigation via the API (LoadURL(), etc). + /// + FOCUS_SOURCE_NAVIGATION = 0, + /// + // The source is a system-generated focus event. + /// + FOCUS_SOURCE_SYSTEM, +}; + +/// +// Navigation types. +/// +enum cef_navigation_type_t { + NAVIGATION_LINK_CLICKED = 0, + NAVIGATION_FORM_SUBMITTED, + NAVIGATION_BACK_FORWARD, + NAVIGATION_RELOAD, + NAVIGATION_FORM_RESUBMITTED, + NAVIGATION_OTHER, +}; + +/// +// Supported XML encoding types. The parser supports ASCII, ISO-8859-1, and +// UTF16 (LE and BE) by default. All other types must be translated to UTF8 +// before being passed to the parser. If a BOM is detected and the correct +// decoder is available then that decoder will be used automatically. +/// +enum cef_xml_encoding_type_t { + XML_ENCODING_NONE = 0, + XML_ENCODING_UTF8, + XML_ENCODING_UTF16LE, + XML_ENCODING_UTF16BE, + XML_ENCODING_ASCII, +}; + +/// +// XML node types. +/// +enum cef_xml_node_type_t { + XML_NODE_UNSUPPORTED = 0, + XML_NODE_PROCESSING_INSTRUCTION, + XML_NODE_DOCUMENT_TYPE, + XML_NODE_ELEMENT_START, + XML_NODE_ELEMENT_END, + XML_NODE_ATTRIBUTE, + XML_NODE_TEXT, + XML_NODE_CDATA, + XML_NODE_ENTITY_REFERENCE, + XML_NODE_WHITESPACE, + XML_NODE_COMMENT, +}; + +/// +// Popup window features. +/// +typedef struct _cef_popup_features_t { + int x; + bool xSet; + int y; + bool ySet; + int width; + bool widthSet; + int height; + bool heightSet; + + bool menuBarVisible; + bool statusBarVisible; + bool toolBarVisible; + bool locationBarVisible; + bool scrollbarsVisible; + bool resizable; + + bool fullscreen; + bool dialog; + cef_string_list_t additionalFeatures; +} cef_popup_features_t; + +/// +// DOM document types. +/// +enum cef_dom_document_type_t { + DOM_DOCUMENT_TYPE_UNKNOWN = 0, + DOM_DOCUMENT_TYPE_HTML, + DOM_DOCUMENT_TYPE_XHTML, + DOM_DOCUMENT_TYPE_PLUGIN, +}; + +/// +// DOM event category flags. +/// +enum cef_dom_event_category_t { + DOM_EVENT_CATEGORY_UNKNOWN = 0x0, + DOM_EVENT_CATEGORY_UI = 0x1, + DOM_EVENT_CATEGORY_MOUSE = 0x2, + DOM_EVENT_CATEGORY_MUTATION = 0x4, + DOM_EVENT_CATEGORY_KEYBOARD = 0x8, + DOM_EVENT_CATEGORY_TEXT = 0x10, + DOM_EVENT_CATEGORY_COMPOSITION = 0x20, + DOM_EVENT_CATEGORY_DRAG = 0x40, + DOM_EVENT_CATEGORY_CLIPBOARD = 0x80, + DOM_EVENT_CATEGORY_MESSAGE = 0x100, + DOM_EVENT_CATEGORY_WHEEL = 0x200, + DOM_EVENT_CATEGORY_BEFORE_TEXT_INSERTED = 0x400, + DOM_EVENT_CATEGORY_OVERFLOW = 0x800, + DOM_EVENT_CATEGORY_PAGE_TRANSITION = 0x1000, + DOM_EVENT_CATEGORY_POPSTATE = 0x2000, + DOM_EVENT_CATEGORY_PROGRESS = 0x4000, + DOM_EVENT_CATEGORY_XMLHTTPREQUEST_PROGRESS = 0x8000, + DOM_EVENT_CATEGORY_BEFORE_LOAD = 0x10000, +}; + +/// +// DOM event processing phases. +/// +enum cef_dom_event_phase_t { + DOM_EVENT_PHASE_UNKNOWN = 0, + DOM_EVENT_PHASE_CAPTURING, + DOM_EVENT_PHASE_AT_TARGET, + DOM_EVENT_PHASE_BUBBLING, +}; + +/// +// DOM node types. +/// +enum cef_dom_node_type_t { + DOM_NODE_TYPE_UNSUPPORTED = 0, + DOM_NODE_TYPE_ELEMENT, + DOM_NODE_TYPE_ATTRIBUTE, + DOM_NODE_TYPE_TEXT, + DOM_NODE_TYPE_CDATA_SECTION, + DOM_NODE_TYPE_ENTITY, + DOM_NODE_TYPE_PROCESSING_INSTRUCTIONS, + DOM_NODE_TYPE_COMMENT, + DOM_NODE_TYPE_DOCUMENT, + DOM_NODE_TYPE_DOCUMENT_TYPE, + DOM_NODE_TYPE_DOCUMENT_FRAGMENT, + DOM_NODE_TYPE_NOTATION, + DOM_NODE_TYPE_XPATH_NAMESPACE, +}; + +/// +// Supported file dialog modes. +/// +enum cef_file_dialog_mode_t { + /// + // Requires that the file exists before allowing the user to pick it. + /// + FILE_DIALOG_OPEN = 0, + + /// + // Like Open, but allows picking multiple files to open. + /// + FILE_DIALOG_OPEN_MULTIPLE, + + /// + // Allows picking a nonexistent file, and prompts to overwrite if the file + // already exists. + /// + FILE_DIALOG_SAVE, +}; + +/// +// Geoposition error codes. +/// +enum cef_geoposition_error_code_t { + GEOPOSITON_ERROR_NONE = 0, + GEOPOSITON_ERROR_PERMISSION_DENIED, + GEOPOSITON_ERROR_POSITION_UNAVAILABLE, + GEOPOSITON_ERROR_TIMEOUT, +}; + +/// +// Structure representing geoposition information. The properties of this +// structure correspond to those of the JavaScript Position object although +// their types may differ. +/// +typedef struct _cef_geoposition_t { + /// + // Latitude in decimal degrees north (WGS84 coordinate frame). + /// + double latitude; + + /// + // Longitude in decimal degrees west (WGS84 coordinate frame). + /// + double longitude; + + /// + // Altitude in meters (above WGS84 datum). + /// + double altitude; + + /// + // Accuracy of horizontal position in meters. + /// + double accuracy; + + /// + // Accuracy of altitude in meters. + /// + double altitude_accuracy; + + /// + // Heading in decimal degrees clockwise from true north. + /// + double heading; + + /// + // Horizontal component of device velocity in meters per second. + /// + double speed; + + /// + // Time of position measurement in miliseconds since Epoch in UTC time. This + // is taken from the host computer's system clock. + /// + cef_time_t timestamp; + + /// + // Error code, see enum above. + /// + cef_geoposition_error_code_t error_code; + + /// + // Human-readable error message. + /// + cef_string_t error_message; +} cef_geoposition_t; + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_H_ diff --git a/cefpython/cef3/include/internal/cef_types_linux.h b/cefpython/cef3/include/internal/cef_types_linux.h new file mode 100644 index 00000000..33651733 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_types_linux.h @@ -0,0 +1,84 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_LINUX) +#include +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Handle types. +#define cef_cursor_handle_t GdkCursor* +#define cef_event_handle_t GdkEvent* +#define cef_window_handle_t GtkWidget* +#define cef_text_input_context_t void* + +/// +// Structure representing CefExecuteProcess arguments. +/// +typedef struct _cef_main_args_t { + int argc; + char** argv; +} cef_main_args_t; + +/// +// Class representing window information. +/// +typedef struct _cef_window_info_t { + // Pointer for the parent GtkBox widget. + cef_window_handle_t parent_widget; + + // If window rendering is disabled no browser window will be created. Set + // |parent_widget| to the window that will act as the parent for popup menus, + // dialog boxes, etc. + bool window_rendering_disabled; + + // Set to true to enable transparent painting. + bool transparent_painting; + + // Pointer for the new browser widget. + cef_window_handle_t widget; +} cef_window_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_LINUX + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_LINUX_H_ diff --git a/cefpython/cef3/include/internal/cef_types_mac.h b/cefpython/cef3/include/internal/cef_types_mac.h new file mode 100644 index 00000000..7dd997f9 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_types_mac.h @@ -0,0 +1,108 @@ +// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_MACOSX) +#include "include/internal/cef_string.h" + +// Handle types. +#ifdef __cplusplus +#ifdef __OBJC__ +@class NSCursor; +@class NSEvent; +@class NSView; +@class NSTextInputContext; +#else +class NSCursor; +class NSEvent; +struct NSView; +class NSTextInputContext; +#endif +#define cef_cursor_handle_t NSCursor* +#define cef_event_handle_t NSEvent* +#define cef_window_handle_t NSView* +#define cef_text_input_context_t NSTextInputContext* +#else +#define cef_cursor_handle_t void* +#define cef_event_handle_t void* +#define cef_window_handle_t void* +#define cef_text_input_context_t void* +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// Structure representing CefExecuteProcess arguments. +/// +typedef struct _cef_main_args_t { + int argc; + char** argv; +} cef_main_args_t; + +/// +// Class representing window information. +/// +typedef struct _cef_window_info_t { + cef_string_t window_name; + int x; + int y; + int width; + int height; + int hidden; + + // NSView pointer for the parent view. + cef_window_handle_t parent_view; + + // If window rendering is disabled no browser window will be created. Set + // |parent_view| to the window that will act as the parent for popup menus, + // dialog boxes, etc. + bool window_rendering_disabled; + + // Set to true to enable transparent painting. + bool transparent_painting; + + // NSView pointer for the new browser view. + cef_window_handle_t view; +} cef_window_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_MACOSX + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_MAC_H_ diff --git a/cefpython/cef3/include/internal/cef_types_win.h b/cefpython/cef3/include/internal/cef_types_win.h new file mode 100644 index 00000000..8c4693cd --- /dev/null +++ b/cefpython/cef3/include/internal/cef_types_win.h @@ -0,0 +1,95 @@ +// Copyright (c) 2009 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ +#pragma once + +#include "include/internal/cef_build.h" + +#if defined(OS_WIN) +#include +#include "include/internal/cef_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Handle types. +#define cef_cursor_handle_t HCURSOR +#define cef_event_handle_t MSG* +#define cef_window_handle_t HWND +#define cef_text_input_context_t void* + +/// +// Structure representing CefExecuteProcess arguments. +/// +typedef struct _cef_main_args_t { + HINSTANCE instance; +} cef_main_args_t; + +/// +// Structure representing window information. +/// +typedef struct _cef_window_info_t { + // Standard parameters required by CreateWindowEx() + DWORD ex_style; + cef_string_t window_name; + DWORD style; + int x; + int y; + int width; + int height; + cef_window_handle_t parent_window; + HMENU menu; + + // If window rendering is disabled no browser window will be created. Set + // |parent_window| to be used for identifying monitor info + // (MonitorFromWindow). If |parent_window| is not provided the main screen + // monitor will be used. + BOOL window_rendering_disabled; + + // Set to true to enable transparent painting. + // If window rendering is disabled and |transparent_painting| is set to true + // WebKit rendering will draw on a transparent background (RGBA=0x00000000). + // When this value is false the background will be white and opaque. + BOOL transparent_painting; + + // Handle for the new browser window. + cef_window_handle_t window; +} cef_window_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // OS_WIN + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WIN_H_ diff --git a/cefpython/cef3/include/internal/cef_types_wrappers.h b/cefpython/cef3/include/internal/cef_types_wrappers.h new file mode 100644 index 00000000..00c560a7 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_types_wrappers.h @@ -0,0 +1,630 @@ +// Copyright (c) 2013 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ +#define CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ +#pragma once + +#include "include/internal/cef_string.h" +#include "include/internal/cef_string_list.h" +#include "include/internal/cef_types.h" + +/// +// Template class that provides common functionality for CEF structure wrapping. +/// +template +class CefStructBase : public traits::struct_type { + public: + typedef typename traits::struct_type struct_type; + + CefStructBase() : attached_to_(NULL) { + Init(); + } + virtual ~CefStructBase() { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + } + + CefStructBase(const CefStructBase& r) { + Init(); + *this = r; + } + CefStructBase(const struct_type& r) { // NOLINT(runtime/explicit) + Init(); + *this = r; + } + + /// + // Clear this object's values. + /// + void Reset() { + Clear(this); + Init(); + } + + /// + // Attach to the source structure's existing values. DetachTo() can be called + // to insert the values back into the existing structure. + /// + void AttachTo(struct_type& source) { + // Only clear this object's data if it isn't currently attached to a + // structure. + if (!attached_to_) + Clear(this); + + // This object is now attached to the new structure. + attached_to_ = &source; + + // Transfer ownership of the values from the source structure. + memcpy(static_cast(this), &source, sizeof(struct_type)); + } + + /// + // Relinquish ownership of values to the target structure. + /// + void DetachTo(struct_type& target) { + if (attached_to_ != &target) { + // Clear the target structure's values only if we are not currently + // attached to that structure. + Clear(&target); + } + + // Transfer ownership of the values to the target structure. + memcpy(&target, static_cast(this), sizeof(struct_type)); + + // Remove the references from this object. + Init(); + } + + /// + // Set this object's values. If |copy| is true the source structure's values + // will be copied instead of referenced. + /// + void Set(const struct_type& source, bool copy) { + traits::set(&source, this, copy); + } + + CefStructBase& operator=(const CefStructBase& s) { + return operator=(static_cast(s)); + } + + CefStructBase& operator=(const struct_type& s) { + Set(s, true); + return *this; + } + + protected: + void Init() { + memset(static_cast(this), 0, sizeof(struct_type)); + attached_to_ = NULL; + traits::init(this); + } + + static void Clear(struct_type* s) { traits::clear(s); } + + struct_type* attached_to_; +}; + + +struct CefRectTraits { + typedef cef_rect_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing a rectangle. +/// +class CefRect : public CefStructBase { + public: + typedef CefStructBase parent; + + CefRect() : parent() {} + CefRect(const cef_rect_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefRect(const CefRect& r) : parent(r) {} // NOLINT(runtime/explicit) + CefRect(int x, int y, int width, int height) : parent() { + Set(x, y, width, height); + } + + bool IsEmpty() const { return width <= 0 || height <= 0; } + void Set(int x, int y, int width, int height) { + this->x = x, this->y = y, this->width = width, this->height = height; + } +}; + +inline bool operator==(const CefRect& a, const CefRect& b) { + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +} + +inline bool operator!=(const CefRect& a, const CefRect& b) { + return !(a == b); +} + +struct CefScreenInfoTraits { + typedef cef_screen_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->device_scale_factor = src->device_scale_factor; + target->depth = src->depth; + target->depth_per_component = src->depth_per_component; + target->is_monochrome = src->is_monochrome; + target->rect = src->rect; + target->available_rect = src->available_rect; + } +}; + +/// +// Class representing the virtual screen information for use when window rendering +// is disabled. +/// +class CefScreenInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefScreenInfo() : parent() {} + CefScreenInfo(const cef_screen_info_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefScreenInfo(const CefScreenInfo& r) : parent(r) {} // NOLINT(runtime/explicit) + CefScreenInfo(float device_scale_factor, + int depth, + int depth_per_component, + bool is_monochrome, + const CefRect& rect, + const CefRect& available_rect) : parent() { + Set(device_scale_factor, depth, depth_per_component, + is_monochrome, rect, available_rect); + } + + void Set(float device_scale_factor, + int depth, + int depth_per_component, + bool is_monochrome, + const CefRect& rect, + const CefRect& available_rect) { + this->device_scale_factor = device_scale_factor; + this->depth = depth; + this->depth_per_component = depth_per_component; + this->is_monochrome = is_monochrome; + this->rect = rect; + this->available_rect = available_rect; + } +}; + +struct CefKeyEventTraits { + typedef cef_key_event_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->type = src->type; + target->modifiers = src->modifiers; + target->windows_key_code = src->windows_key_code; + target->native_key_code = src->native_key_code; + target->is_system_key = src->is_system_key; + target->character = src->character; + target->unmodified_character = src->unmodified_character; + target->focus_on_editable_field = src->focus_on_editable_field; + } +}; + +/// +// Class representing a a keyboard event. +/// +typedef CefStructBase CefKeyEvent; + +struct CefMouseEventTraits { + typedef cef_mouse_event_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->x = src->x; + target->y = src->y; + target->modifiers = src->modifiers; + } +}; + +/// +// Class representing a mouse event. +/// +typedef CefStructBase CefMouseEvent; + +struct CefPopupFeaturesTraits { + typedef cef_popup_features_t struct_type; + + static inline void init(struct_type* s) { + s->menuBarVisible = true; + s->statusBarVisible = true; + s->toolBarVisible = true; + s->locationBarVisible = true; + s->scrollbarsVisible = true; + s->resizable = true; + } + + static inline void clear(struct_type* s) { + if (s->additionalFeatures) + cef_string_list_free(s->additionalFeatures); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + if (target->additionalFeatures) + cef_string_list_free(target->additionalFeatures); + target->additionalFeatures = src->additionalFeatures ? + cef_string_list_copy(src->additionalFeatures) : NULL; + + target->x = src->x; + target->xSet = src->xSet; + target->y = src->y; + target->ySet = src->ySet; + target->width = src->width; + target->widthSet = src->widthSet; + target->height = src->height; + target->heightSet = src->heightSet; + target->menuBarVisible = src->menuBarVisible; + target->statusBarVisible = src->statusBarVisible; + target->toolBarVisible = src->toolBarVisible; + target->locationBarVisible = src->locationBarVisible; + target->scrollbarsVisible = src->scrollbarsVisible; + target->resizable = src->resizable; + target->fullscreen = src->fullscreen; + target->dialog = src->dialog; + } +}; + +/// +// Class representing popup window features. +/// +typedef CefStructBase CefPopupFeatures; + + +struct CefSettingsTraits { + typedef cef_settings_t struct_type; + + static inline void init(struct_type* s) { + s->size = sizeof(struct_type); + } + + static inline void clear(struct_type* s) { + cef_string_clear(&s->browser_subprocess_path); + cef_string_clear(&s->cache_path); + cef_string_clear(&s->user_agent); + cef_string_clear(&s->product_version); + cef_string_clear(&s->locale); + cef_string_clear(&s->log_file); + cef_string_clear(&s->javascript_flags); + cef_string_clear(&s->resources_dir_path); + cef_string_clear(&s->locales_dir_path); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->single_process = src->single_process; + cef_string_set(src->browser_subprocess_path.str, + src->browser_subprocess_path.length, + &target->browser_subprocess_path, copy); + target->multi_threaded_message_loop = src->multi_threaded_message_loop; + target->command_line_args_disabled = src->command_line_args_disabled; + + cef_string_set(src->cache_path.str, src->cache_path.length, + &target->cache_path, copy); + target->persist_session_cookies = src->persist_session_cookies; + + cef_string_set(src->user_agent.str, src->user_agent.length, + &target->user_agent, copy); + cef_string_set(src->product_version.str, src->product_version.length, + &target->product_version, copy); + cef_string_set(src->locale.str, src->locale.length, &target->locale, copy); + + cef_string_set(src->log_file.str, src->log_file.length, &target->log_file, + copy); + target->log_severity = src->log_severity; + target->release_dcheck_enabled = src->release_dcheck_enabled; + cef_string_set(src->javascript_flags.str, src->javascript_flags.length, + &target->javascript_flags, copy); + + cef_string_set(src->resources_dir_path.str, src->resources_dir_path.length, + &target->resources_dir_path, copy); + cef_string_set(src->locales_dir_path.str, src->locales_dir_path.length, + &target->locales_dir_path, copy); + target->pack_loading_disabled = src->pack_loading_disabled; + target->remote_debugging_port = src->remote_debugging_port; + target->uncaught_exception_stack_size = src->uncaught_exception_stack_size; + target->context_safety_implementation = src->context_safety_implementation; + target->ignore_certificate_errors = src->ignore_certificate_errors; + target->background_color = src->background_color; + } +}; + +/// +// Class representing initialization settings. +/// +typedef CefStructBase CefSettings; + + +struct CefBrowserSettingsTraits { + typedef cef_browser_settings_t struct_type; + + static inline void init(struct_type* s) { + s->size = sizeof(struct_type); + } + + static inline void clear(struct_type* s) { + cef_string_clear(&s->standard_font_family); + cef_string_clear(&s->fixed_font_family); + cef_string_clear(&s->serif_font_family); + cef_string_clear(&s->sans_serif_font_family); + cef_string_clear(&s->cursive_font_family); + cef_string_clear(&s->fantasy_font_family); + cef_string_clear(&s->default_encoding); + cef_string_clear(&s->user_style_sheet_location); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + cef_string_set(src->standard_font_family.str, + src->standard_font_family.length, &target->standard_font_family, copy); + cef_string_set(src->fixed_font_family.str, src->fixed_font_family.length, + &target->fixed_font_family, copy); + cef_string_set(src->serif_font_family.str, src->serif_font_family.length, + &target->serif_font_family, copy); + cef_string_set(src->sans_serif_font_family.str, + src->sans_serif_font_family.length, &target->sans_serif_font_family, + copy); + cef_string_set(src->cursive_font_family.str, + src->cursive_font_family.length, &target->cursive_font_family, copy); + cef_string_set(src->fantasy_font_family.str, + src->fantasy_font_family.length, &target->fantasy_font_family, copy); + + target->default_font_size = src->default_font_size; + target->default_fixed_font_size = src->default_fixed_font_size; + target->minimum_font_size = src->minimum_font_size; + target->minimum_logical_font_size = src->minimum_logical_font_size; + + cef_string_set(src->default_encoding.str, src->default_encoding.length, + &target->default_encoding, copy); + + cef_string_set(src->user_style_sheet_location.str, + src->user_style_sheet_location.length, + &target->user_style_sheet_location, copy); + + target->remote_fonts = src->remote_fonts; + target->javascript = src->javascript; + target->javascript_open_windows = src->javascript_open_windows; + target->javascript_close_windows = src->javascript_close_windows; + target->javascript_access_clipboard = src->javascript_access_clipboard; + target->javascript_dom_paste = src->javascript_dom_paste; + target->caret_browsing = src->caret_browsing; + target->java = src->java; + target->plugins = src->plugins; + target->universal_access_from_file_urls = + src->universal_access_from_file_urls; + target->file_access_from_file_urls = src->file_access_from_file_urls; + target->web_security = src->web_security; + target->image_loading = src->image_loading; + target->image_shrink_standalone_to_fit = + src->image_shrink_standalone_to_fit; + target->text_area_resize = src->text_area_resize; + target->tab_to_links = src->tab_to_links; + target->author_and_user_styles = src->author_and_user_styles; + target->local_storage = src->local_storage; + target->databases= src->databases; + target->application_cache = src->application_cache; + target->webgl = src->webgl; + target->accelerated_compositing = src->accelerated_compositing; + } +}; + +/// +// Class representing browser initialization settings. +/// +typedef CefStructBase CefBrowserSettings; + + +struct CefURLPartsTraits { + typedef cef_urlparts_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->spec); + cef_string_clear(&s->scheme); + cef_string_clear(&s->username); + cef_string_clear(&s->password); + cef_string_clear(&s->host); + cef_string_clear(&s->port); + cef_string_clear(&s->path); + cef_string_clear(&s->query); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + cef_string_set(src->spec.str, src->spec.length, &target->spec, copy); + cef_string_set(src->scheme.str, src->scheme.length, &target->scheme, copy); + cef_string_set(src->username.str, src->username.length, &target->username, + copy); + cef_string_set(src->password.str, src->password.length, &target->password, + copy); + cef_string_set(src->host.str, src->host.length, &target->host, copy); + cef_string_set(src->port.str, src->port.length, &target->port, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + cef_string_set(src->query.str, src->query.length, &target->query, copy); + } +}; + +/// +// Class representing a URL's component parts. +/// +typedef CefStructBase CefURLParts; + + +struct CefTimeTraits { + typedef cef_time_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing a time. +/// +class CefTime : public CefStructBase { + public: + typedef CefStructBase parent; + + CefTime() : parent() {} + CefTime(const cef_time_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefTime(const CefTime& r) : parent(r) {} // NOLINT(runtime/explicit) + explicit CefTime(time_t r) : parent() { SetTimeT(r); } + explicit CefTime(double r) : parent() { SetDoubleT(r); } + + // Converts to/from time_t. + void SetTimeT(time_t r) { + cef_time_from_timet(r, this); + } + time_t GetTimeT() const { + time_t time = 0; + cef_time_to_timet(this, &time); + return time; + } + + // Converts to/from a double which is the number of seconds since epoch + // (Jan 1, 1970). Webkit uses this format to represent time. A value of 0 + // means "not initialized". + void SetDoubleT(double r) { + cef_time_from_doublet(r, this); + } + double GetDoubleT() const { + double time = 0; + cef_time_to_doublet(this, &time); + return time; + } + + // Set this object to now. + void Now() { + cef_time_now(this); + } + + // Return the delta between this object and |other| in milliseconds. + long long Delta(const CefTime& other) { + long long delta = 0; + cef_time_delta(this, &other, &delta); + return delta; + } +}; + + +struct CefCookieTraits { + typedef cef_cookie_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->name); + cef_string_clear(&s->value); + cef_string_clear(&s->domain); + cef_string_clear(&s->path); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + cef_string_set(src->name.str, src->name.length, &target->name, copy); + cef_string_set(src->value.str, src->value.length, &target->value, copy); + cef_string_set(src->domain.str, src->domain.length, &target->domain, copy); + cef_string_set(src->path.str, src->path.length, &target->path, copy); + target->secure = src->secure; + target->httponly = src->httponly; + target->creation = src->creation; + target->last_access = src->last_access; + target->has_expires = src->has_expires; + target->expires = src->expires; + } +}; + +/// +// Class representing a cookie. +/// +typedef CefStructBase CefCookie; + + +struct CefGeopositionTraits { + typedef cef_geoposition_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->error_message); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->latitude = src->latitude; + target->longitude = src->longitude; + target->altitude = src->altitude; + target->accuracy = src->accuracy; + target->altitude_accuracy = src->altitude_accuracy; + target->heading = src->heading; + target->speed = src->speed; + target->timestamp = src->timestamp; + target->error_code = src->error_code; + cef_string_set(src->error_message.str, src->error_message.length, + &target->error_message, copy); + } +}; + +/// +// Class representing a geoposition. +/// +typedef CefStructBase CefGeoposition; + +#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ diff --git a/cefpython/cef3/include/internal/cef_win.h b/cefpython/cef3/include/internal/cef_win.h new file mode 100644 index 00000000..29e26c45 --- /dev/null +++ b/cefpython/cef3/include/internal/cef_win.h @@ -0,0 +1,173 @@ +// Copyright (c) 2008 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef CEF_INCLUDE_INTERNAL_CEF_WIN_H_ +#define CEF_INCLUDE_INTERNAL_CEF_WIN_H_ +#pragma once + +#if defined(OS_WIN) +#include +#include "include/internal/cef_types_win.h" +#include "include/internal/cef_types_wrappers.h" + +/// +// Atomic increment and decrement. +/// +#define CefAtomicIncrement(p) InterlockedIncrement(p) +#define CefAtomicDecrement(p) InterlockedDecrement(p) + +/// +// Critical section wrapper. +/// +class CefCriticalSection { + public: + CefCriticalSection() { + memset(&m_sec, 0, sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(&m_sec); + } + virtual ~CefCriticalSection() { + DeleteCriticalSection(&m_sec); + } + void Lock() { + EnterCriticalSection(&m_sec); + } + void Unlock() { + LeaveCriticalSection(&m_sec); + } + + CRITICAL_SECTION m_sec; +}; + +/// +// Handle types. +/// +#define CefCursorHandle cef_cursor_handle_t +#define CefEventHandle cef_event_handle_t +#define CefWindowHandle cef_window_handle_t +#define CefTextInputContext cef_text_input_context_t + +struct CefMainArgsTraits { + typedef cef_main_args_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->instance = src->instance; + } +}; + +// Class representing CefExecuteProcess arguments. +class CefMainArgs : public CefStructBase { + public: + typedef CefStructBase parent; + + CefMainArgs() : parent() {} + explicit CefMainArgs(const cef_main_args_t& r) : parent(r) {} + explicit CefMainArgs(const CefMainArgs& r) : parent(r) {} + explicit CefMainArgs(HINSTANCE hInstance) : parent() { + instance = hInstance; + } +}; + +struct CefWindowInfoTraits { + typedef cef_window_info_t struct_type; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->window_name); + } + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + target->ex_style = src->ex_style; + cef_string_set(src->window_name.str, src->window_name.length, + &target->window_name, copy); + target->style = src->style; + target->x = src->x; + target->y = src->y; + target->width = src->width; + target->height = src->height; + target->parent_window = src->parent_window; + target->menu = src->menu; + target->window = src->window; + target->transparent_painting = src->transparent_painting; + target->window_rendering_disabled = src->window_rendering_disabled; + } +}; + +/// +// Class representing window information. +/// +class CefWindowInfo : public CefStructBase { + public: + typedef CefStructBase parent; + + CefWindowInfo() : parent() {} + explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {} + explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {} + + void SetAsChild(HWND hWndParent, RECT windowRect) { + style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP | + WS_VISIBLE; + parent_window = hWndParent; + x = windowRect.left; + y = windowRect.top; + width = windowRect.right - windowRect.left; + height = windowRect.bottom - windowRect.top; + } + + void SetAsPopup(HWND hWndParent, const CefString& windowName) { + style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | + WS_VISIBLE; + parent_window = hWndParent; + x = CW_USEDEFAULT; + y = CW_USEDEFAULT; + width = CW_USEDEFAULT; + height = CW_USEDEFAULT; + + cef_string_copy(windowName.c_str(), windowName.length(), &window_name); + } + + void SetTransparentPainting(BOOL transparentPainting) { + transparent_painting = transparentPainting; + } + + void SetAsOffScreen(HWND hWndParent) { + window_rendering_disabled = TRUE; + parent_window = hWndParent; + } +}; + +#endif // OS_WIN + +#endif // CEF_INCLUDE_INTERNAL_CEF_WIN_H_ diff --git a/cefpython/cef3/include/wrapper/cef_byte_read_handler.h b/cefpython/cef3/include/wrapper/cef_byte_read_handler.h new file mode 100644 index 00000000..1752588d --- /dev/null +++ b/cefpython/cef3/include/wrapper/cef_byte_read_handler.h @@ -0,0 +1,74 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ +#define CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_stream.h" + +/// +// Thread safe implementation of the CefReadHandler class for reading an +// in-memory array of bytes. +/// +class CefByteReadHandler : public CefReadHandler { + public: + /// + // Create a new object for reading an array of bytes. An optional |source| + // reference can be kept to keep the underlying data source from being + // released while the reader exists. + /// + CefByteReadHandler(const unsigned char* bytes, + size_t size, + CefRefPtr source); + + // CefReadHandler methods. + virtual size_t Read(void* ptr, size_t size, size_t n) OVERRIDE; + virtual int Seek(int64 offset, int whence) OVERRIDE; + virtual int64 Tell() OVERRIDE; + virtual int Eof() OVERRIDE; + + private: + const unsigned char* bytes_; + int64 size_; + int64 offset_; + CefRefPtr source_; + + IMPLEMENT_REFCOUNTING(CefByteReadHandler); + IMPLEMENT_LOCKING(CefByteReadHandler); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_BYTE_READ_HANDLER_H_ diff --git a/cefpython/cef3/include/wrapper/cef_stream_resource_handler.h b/cefpython/cef3/include/wrapper/cef_stream_resource_handler.h new file mode 100644 index 00000000..181bbbfe --- /dev/null +++ b/cefpython/cef3/include/wrapper/cef_stream_resource_handler.h @@ -0,0 +1,85 @@ +// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_STREAM_RESOURCE_HANDLER_H_ +#define CEF_INCLUDE_WRAPPER_CEF_STREAM_RESOURCE_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_resource_handler.h" +#include "include/cef_response.h" + +class CefStreamReader; + +/// +// Implementation of the CefResourceHandler class for reading from a CefStream. +/// +class CefStreamResourceHandler : public CefResourceHandler { + public: + /// + // Create a new object with default response values. + /// + CefStreamResourceHandler(const CefString& mime_type, + CefRefPtr stream); + /// + // Create a new object with explicit response values. + /// + CefStreamResourceHandler(int status_code, + const CefString& mime_type, + CefResponse::HeaderMap header_map, + CefRefPtr stream); + + // CefStreamResourceHandler methods. + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) OVERRIDE; + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) OVERRIDE; + virtual bool ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) OVERRIDE; + virtual void Cancel() OVERRIDE; + + private: + int status_code_; + CefString mime_type_; + CefResponse::HeaderMap header_map_; + CefRefPtr stream_; + + IMPLEMENT_REFCOUNTING(CefStreamResourceHandler); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_STREAM_RESOURCE_HANDLER_H_ diff --git a/cefpython/cef3/include/wrapper/cef_xml_object.h b/cefpython/cef3/include/wrapper/cef_xml_object.h new file mode 100644 index 00000000..d9f706fd --- /dev/null +++ b/cefpython/cef3/include/wrapper/cef_xml_object.h @@ -0,0 +1,188 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ +#define CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_xml_reader.h" +#include +#include + +class CefStreamReader; + +/// +// Thread safe class for representing XML data as a structured object. This +// class should not be used with large XML documents because all data will be +// resident in memory at the same time. This implementation supports a +// restricted set of XML features: +//
+// (1) Processing instructions, whitespace and comments are ignored.
+// (2) Elements and attributes must always be referenced using the fully
+//     qualified name (ie, namespace:localname).
+// (3) Empty elements () and elements with zero-length values ()
+//     are considered the same.
+// (4) Element nodes are considered part of a value if:
+//     (a) The element node follows a non-element node at the same depth
+//         (see 5), or
+//     (b) The element node does not have a namespace and the parent node does.
+// (5) Mixed node types at the same depth are combined into a single element
+//     value as follows:
+//     (a) All node values are concatenated to form a single string value.
+//     (b) Entity reference nodes are resolved to the corresponding entity
+//         value.
+//     (c) Element nodes are represented by their outer XML string.
+// 
+/// +class CefXmlObject : public CefBase { + public: + typedef std::vector > ObjectVector; + typedef std::map AttributeMap; + + /// + // Create a new object with the specified name. An object name must always be + // at least one character long. + /// + explicit CefXmlObject(const CefString& name); + virtual ~CefXmlObject(); + + /// + // Load the contents of the specified XML stream into this object. The + // existing children and attributes, if any, will first be cleared. + /// + bool Load(CefRefPtr stream, + CefXmlReader::EncodingType encodingType, + const CefString& URI, CefString* loadError); + + /// + // Set the name, children and attributes of this object to a duplicate of the + // specified object's contents. The existing children and attributes, if any, + // will first be cleared. + /// + void Set(CefRefPtr object); + + /// + // Append a duplicate of the children and attributes of the specified object + // to this object. If |overwriteAttributes| is true then any attributes in + // this object that also exist in the specified object will be overwritten + // with the new values. The name of this object is not changed. + /// + void Append(CefRefPtr object, bool overwriteAttributes); + + /// + // Return a new object with the same name, children and attributes as this + // object. The parent of the new object will be NULL. + /// + CefRefPtr Duplicate(); + + /// + // Clears this object's children and attributes. The name and parenting of + // this object are not changed. + /// + void Clear(); + + /// + // Access the object's name. An object name must always be at least one + // character long. + /// + CefString GetName(); + bool SetName(const CefString& name); + + /// + // Access the object's parent. The parent can be NULL if this object has not + // been added as the child on another object. + /// + bool HasParent(); + CefRefPtr GetParent(); + + /// + // Access the object's value. An object cannot have a value if it also has + // children. Attempting to set the value while children exist will fail. + /// + bool HasValue(); + CefString GetValue(); + bool SetValue(const CefString& value); + + /// + // Access the object's attributes. Attributes must have unique names. + /// + bool HasAttributes(); + size_t GetAttributeCount(); + bool HasAttribute(const CefString& name); + CefString GetAttributeValue(const CefString& name); + bool SetAttributeValue(const CefString& name, const CefString& value); + size_t GetAttributes(AttributeMap& attributes); + void ClearAttributes(); + + /// + // Access the object's children. Each object can only have one parent so + // attempting to add an object that already has a parent will fail. Removing a + // child will set the child's parent to NULL. Adding a child will set the + // child's parent to this object. This object's value, if any, will be cleared + // if a child is added. + /// + bool HasChildren(); + size_t GetChildCount(); + bool HasChild(CefRefPtr child); + bool AddChild(CefRefPtr child); + bool RemoveChild(CefRefPtr child); + size_t GetChildren(ObjectVector& children); + void ClearChildren(); + + /// + // Find the first child with the specified name. + /// + CefRefPtr FindChild(const CefString& name); + + /// + // Find all children with the specified name. + /// + size_t FindChildren(const CefString& name, ObjectVector& children); + + private: + void SetParent(CefXmlObject* parent); + + CefString name_; + CefXmlObject* parent_; + CefString value_; + AttributeMap attributes_; + ObjectVector children_; + + IMPLEMENT_REFCOUNTING(CefXmlObject); + IMPLEMENT_LOCKING(CefXmlObject); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_XML_OBJECT_H_ diff --git a/cefpython/cef3/include/wrapper/cef_zip_archive.h b/cefpython/cef3/include/wrapper/cef_zip_archive.h new file mode 100644 index 00000000..4e37d69a --- /dev/null +++ b/cefpython/cef3/include/wrapper/cef_zip_archive.h @@ -0,0 +1,135 @@ +// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file are only available to applications that link +// against the libcef_dll_wrapper target. +// + +#ifndef CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ +#define CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ +#pragma once + +#include "include/cef_base.h" +#include + +class CefStreamReader; + +/// +// Thread-safe class for accessing zip archive file contents. This class should +// not be used with large archive files because all data will be resident in +// memory at the same time. This implementation supports a restricted set of zip +// archive features: +// (1) Password-protected files are not supported. +// (2) All file names are stored and compared in lower case. +// (3) File ordering from the original zip archive is not maintained. This +// means that files from the same folder may not be located together in the +// file content map. +/// +class CefZipArchive : public CefBase { + public: + /// + // Class representing a file in the archive. Accessing the file data from + // multiple threads is safe provided a reference to the File object is kept. + /// + class File : public CefBase { + public: + /// + // Returns the read-only data contained in the file. + /// + virtual const unsigned char* GetData() =0; + + /// + // Returns the size of the data in the file. + /// + virtual size_t GetDataSize() =0; + + /// + // Returns a CefStreamReader object for streaming the contents of the file. + /// + virtual CefRefPtr GetStreamReader() =0; + }; + typedef std::map > FileMap; + + /// + // Create a new object. + /// + CefZipArchive(); + virtual ~CefZipArchive(); + + /// + // Load the contents of the specified zip archive stream into this object. + // If the zip archive requires a password then provide it via |password|. + // If |overwriteExisting| is true then any files in this object that also + // exist in the specified archive will be replaced with the new files. + // Returns the number of files successfully loaded. + /// + size_t Load(CefRefPtr stream, + const CefString& password, + bool overwriteExisting); + + /// + // Clears the contents of this object. + /// + void Clear(); + + /// + // Returns the number of files in the archive. + /// + size_t GetFileCount(); + + /// + // Returns true if the specified file exists and has contents. + /// + bool HasFile(const CefString& fileName); + + /// + // Returns the specified file. + /// + CefRefPtr GetFile(const CefString& fileName); + + /// + // Removes the specified file. + /// + bool RemoveFile(const CefString& fileName); + + /// + // Returns the map of all files. + /// + size_t GetFiles(FileMap& map); + + private: + FileMap contents_; + + IMPLEMENT_REFCOUNTING(CefZipArchive); + IMPLEMENT_LOCKING(CefZipArchive); +}; + +#endif // CEF_INCLUDE_WRAPPER_CEF_ZIP_ARCHIVE_H_ diff --git a/cefpython/cef3/linux/.gitignore b/cefpython/cef3/linux/.gitignore new file mode 100644 index 00000000..b4581663 --- /dev/null +++ b/cefpython/cef3/linux/.gitignore @@ -0,0 +1,7 @@ +*.pak +cefclient +*.so +subprocess +*.a +*.o +files/ diff --git a/cefpython/cef3/linux/CEF-GTK-patch.txt b/cefpython/cef3/linux/CEF-GTK-patch.txt new file mode 100644 index 00000000..f9658215 --- /dev/null +++ b/cefpython/cef3/linux/CEF-GTK-patch.txt @@ -0,0 +1,56 @@ +See this topic on the CEF C++ forum for more details: +http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10641 + +Do the following changes in the CEF C++ sources: + +1. In `chromium/src/cef/libcef/browser/browser_host_impl_gtk.cc`: + + At the end of the CefBrowserHostImpl::PlatformCreateWindow() function, + before the return statement add the following code: + + gtk_widget_show_all(GTK_WIDGET(window_info_.widget)); + + In the same function replace this code: + + gtk_container_add(GTK_CONTAINER(window_info_.parent_widget), + window_info_.widget); + + With the following code: + + if (GTK_IS_BOX(window_info_.parent_widget)) { + gtk_box_pack_start(GTK_BOX(window_info_.parent_widget), + window_info_.widget, TRUE, TRUE, 0); + } else { + // Parent view shouldn't contain any children, but in wxWidgets library + // there will be GtkPizza widget for Panel or any other control. + GList *children, *iter; + children = gtk_container_get_children(GTK_CONTAINER( + window_info_.parent_widget)); + GtkWidget* child = NULL; + GtkWidget* vbox = gtk_vbox_new(FALSE, 0); + for (iter = children; iter != NULL; iter = g_list_next(iter)) { + child = GTK_WIDGET(iter->data); + // We will have to keep a reference to that child that we remove, + // otherwise we will get lots of warnings like "invalid unclassed + // pointer in cast to `GtkPizza'". First we increase a reference, + // we need to do this for a moment before we add this child to the + // vbox, then we will decrease that reference. + g_object_ref(G_OBJECT(child)); + gtk_container_remove(GTK_CONTAINER(window_info_.parent_widget), child); + } + g_list_free(children); + gtk_box_pack_start(GTK_BOX(vbox), window_info_.widget, TRUE, TRUE, 0); + if (child != NULL) { + // This child is packed to the box only so that its reference lives, + // as it might be referenced from other code thus resulting in errors. + gtk_box_pack_end(GTK_BOX(vbox), child, FALSE, FALSE, 0); + gtk_widget_hide(GTK_WIDGET(child)); + g_object_unref(G_OBJECT(child)); + } + gtk_widget_show(GTK_WIDGET(vbox)); + if (GTK_IS_SCROLLED_WINDOW(window_info_.parent_widget)) + gtk_scrolled_window_add_with_viewport( + GTK_SCROLLED_WINDOW(window_info_.parent_widget), vbox); + else + gtk_container_add(GTK_CONTAINER(window_info_.parent_widget), vbox); + } diff --git a/cefpython/cef3/linux/binaries_32bit/LICENSE.txt b/cefpython/cef3/linux/binaries_32bit/LICENSE.txt new file mode 100644 index 00000000..ba1b96ff --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright (c) 2012-2014 The CEF Python authors. All rights +reserved. Website: http://code.google.com/p/cefpython/ + +This product includes the following third party libraries: +* Chromium Embedded Framework licensed under the BSD 3-clause + license. Website: http://code.google.com/p/chromiumembedded/ + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef3/linux/binaries_32bit/README.txt b/cefpython/cef3/linux/binaries_32bit/README.txt new file mode 100644 index 00000000..a0d3466b --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/README.txt @@ -0,0 +1,97 @@ +Chromium Embedded Framework (CEF) Standard Binary Distribution for Linux +------------------------------------------------------------------------------- + +Date: August 01, 2014 + +CEF Version: 3.1650.1639 +CEF URL: http://chromiumembedded.googlecode.com/svn/branches/1650/cef3@1639 + +Chromium Verison: 31.0.1650.69 +Chromium URL: http://src.chromium.org/svn/branches/1650/src@241641 + +This distribution contains all components necessary to build and distribute an +application using CEF on the Linux platform. Please see the LICENSING +section of this document for licensing terms and conditions. + + +CONTENTS +-------- + +cefclient Contains the cefclient sample application configured to build + using the files in this distribution. + +Debug Contains libcef.so and other components required to run the debug + version of CEF-based applications. By default these files should be + placed in the same directory as the executable and will be copied + there as part of the build process. + +include Contains all required CEF header files. + +libcef_dll Contains the source code for the libcef_dll_wrapper static library + that all applications using the CEF C++ API must link against. + +Release Contains libcef.so and other components required to run the release + version of CEF-based applications. By default these files should be + placed in the same directory as the executable and will be copied + there as part of the build process. + +Resources Contains resources required by libcef.so. By default these files + should be placed in the same directory as libcef.so and will be + copied there as part of the build process. + + +USAGE +----- + +Run 'build.sh Debug' to build the cefclient target in Debug mode. + +Please visit the CEF Website for additional usage information. + +http://code.google.com/p/chromiumembedded + + +REDISTRIBUTION +-------------- + +This binary distribution contains the below components. Components listed under +the "required" section must be redistributed with all applications using CEF. +Components listed under the "optional" section may be excluded if the related +features will not be used. + +Required components: + +* CEF core library + libcef.so + +Optional components: + +* Localized resources + locales/ + Note: Contains localized strings for WebKit UI controls. A .pak file is loaded + from this folder based on the value of environment variables which are read + with the following precedence order: LANGUAGE, LC_ALL, LC_MESSAGES and LANG. + Only configured locales need to be distributed. If no locale is configured the + default locale of "en-US" will be used. Locale file loading can be disabled + completely using CefSettings.pack_loading_disabled. The locales folder path + can be customized using CefSettings.locales_dir_path. + +* Other resources + cef.pak + devtools_resources.pak + Note: Contains WebKit image and inspector resources. Pack file loading can be + disabled completely using CefSettings.pack_loading_disabled. The resources + directory path can be customized using CefSettings.resources_dir_path. + +* FFmpeg audio and video support + libffmpegsumo.so + Note: Without this component HTML5 audio and video will not function. + + +LICENSING +--------- + +The CEF project is BSD licensed. Please read the LICENSE.txt file included with +this binary distribution for licensing terms and conditions. Other software +included in this distribution is provided under other licenses. Please visit +"about:credits" in a CEF-based application for complete Chromium and third-party +licensing information. diff --git a/cefpython/cef3/linux/binaries_32bit/example.html b/cefpython/cef3/linux/binaries_32bit/example.html new file mode 100644 index 00000000..891bc5e8 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/example.html @@ -0,0 +1,58 @@ + + + + + CEF Python 3 example (utf-8: ąś) + + + + + + +

Use mouse context menu to go Back/Forward in history navigation.

+ + + +

Google Search

+https://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('example.html') + + + +

HTML5 video and accelerated content

+ +HTML 5 video
+ +Accelerated canvas
+ +Accelerated layers
+ + + +

Advanced example

+ +See the wxpython.py script for an advanced usage of CEF Python 3 +features - including javascript bindings, js and python callbacks, +client handlers and others. + + +



+



+



+



+ + + diff --git a/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.css b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.css new file mode 100755 index 00000000..46ce5e40 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.css @@ -0,0 +1,186 @@ +/* + IMPORTANT: + 1. DO NOT USE DOUBLE QUOTES HERE! + This file contents is included on page using document.write: + | (DQ = double quote) + | document.write(DQDQ); + 2. Each attribute must end with a semicolon, as newlines are removed + from this file. +*/ + +/* Dropdown control */ +.__kivy__selectBox-dropdown { + min-width: 150px; + position: relative; + border: solid 1px #BBB; + line-height: 1.5; + text-decoration: none; + text-align: left; + color: #000; + outline: none; + vertical-align: middle; + background: #F2F2F2; + background: -moz-linear-gradient(top, #F8F8F8 1%, #E1E1E1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(1%, #F8F8F8), color-stop(100%, #E1E1E1)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F8F8F8', endColorstr='#E1E1E1', GradientType=0); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + display: inline-block; + cursor: default; +} + +.__kivy__selectBox-dropdown:focus, +.__kivy__selectBox-dropdown:focus .__kivy__selectBox-arrow { + border-color: #666; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-menuShowing-bottom { + -moz-border-radius-bottomleft: 0; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-left-radius: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-menuShowing-top { + -moz-border-radius-topleft: 0; + -moz-border-radius-topright: 0; + -webkit-border-top-left-radius: 0; + -webkit-border-top-right-radius: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.__kivy__selectBox-dropdown .__kivy__selectBox-label { + padding: 2px 8px; + display: inline-block; + white-space: nowrap; + overflow: hidden; +} + +.__kivy__selectBox-dropdown .__kivy__selectBox-arrow { + position: absolute; + top: 0; + right: 0; + width: 23px; + height: 100%; + background: url(data:image/gif;base64,R0lGODlhCQAOAIABAAAAAP///yH5BAEAAAEALAAAAAAJAA4AAAIXjAOnwIrcDJxvQoez3tUmn0jUEjmhUQAAOw==) 50% center no-repeat; + border-left: solid 1px #BBB; +} + +/* Dropdown menu */ +.__kivy__selectBox-dropdown-menu { + position: absolute; + z-index: 99999; + max-height: 200px; + min-height: 1em; + border: solid 1px #BBB; /* should be the same border width as .__kivy__selectBox-dropdown */ + background: #FFF; + -moz-box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +/* Inline control */ +.__kivy__selectBox-inline { + min-width: 150px; + outline: none; + border: solid 1px #BBB; + background: #FFF; + display: inline-block; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + overflow: auto; +} + +.__kivy__selectBox-inline:focus { + border-color: #666; +} + +/* Options */ +.__kivy__selectBox-options, +.__kivy__selectBox-options LI, +.__kivy__selectBox-options LI A { + list-style: none; + display: block; + cursor: default; + padding: 0; + margin: 0; +} + +.__kivy__selectBox-options.__kivy__selectBox-options-top{ + border-bottom:none; + margin-top:1px; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} +.__kivy__selectBox-options.__kivy__selectBox-options-bottom{ + border-top:none; + -moz-border-radius-bottomleft: 5px; + -moz-border-radius-bottomright: 5px; + -webkit-border-bottom-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +.__kivy__selectBox-options LI A { + line-height: 1.5; + padding: 0 .5em; + white-space: nowrap; + overflow: hidden; + background: 6px center no-repeat; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-hover A { + background-color: #EEE; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-disabled A { + color: #888; + background-color: transparent; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-selected A { + background-color: #C8DEF4; +} + +.__kivy__selectBox-options .__kivy__selectBox-optgroup { + color: #666; + background: #EEE; + font-weight: bold; + line-height: 1.5; + padding: 0 .3em; + white-space: nowrap; +} + +/* Disabled state */ +.__kivy__selectBox.__kivy__selectBox-disabled { + color: #888 !important; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-disabled .__kivy__selectBox-arrow { + opacity: .5; + filter: alpha(opacity=50); + border-color: #666; +} + +.__kivy__selectBox-inline.__kivy__selectBox-disabled { + color: #888 !important; +} + +.__kivy__selectBox-inline.__kivy__selectBox-disabled .__kivy__selectBox-options A { + background-color: transparent !important; +} diff --git a/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.js b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.js new file mode 100755 index 00000000..a7d3d229 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/kivy-selectBox.js @@ -0,0 +1,10420 @@ +/*! + * __kivy__jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var __kivy__jQuery = (function() { + +// Define a local copy of __kivy__jQuery +var __kivy__jQuery = function( selector, context ) { + // The __kivy__jQuery object is actually just the init constructor 'enhanced' + return new __kivy__jQuery.fn.init( selector, context, root__kivy__jQuery ); + }, + + // Map over __kivy__jQuery in case of overwrite + ___kivy__jQuery = window.__kivy__jQuery, + + // Map over the $ in case of overwrite + __kivy___$ = window.__kivy__$, + + // A central reference to the root __kivy__jQuery(document) + root__kivy__jQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by __kivy__jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with __kivy__jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +__kivy__jQuery.fn = __kivy__jQuery.prototype = { + constructor: __kivy__jQuery, + init: function( selector, context, root__kivy__jQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof __kivy__jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( __kivy__jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + __kivy__jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = __kivy__jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? __kivy__jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return __kivy__jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return root__kivy__jQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the __kivy__jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.__kivy__jquery ) { + return ( context || root__kivy__jQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( __kivy__jQuery.isFunction( selector ) ) { + return root__kivy__jQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return __kivy__jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of __kivy__jQuery being used + __kivy__jquery: "1.7.1", + + // The default length of a __kivy__jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new __kivy__jQuery matched element set + var ret = this.constructor(); + + if ( __kivy__jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + __kivy__jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return __kivy__jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + __kivy__jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( __kivy__jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a __kivy__jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the __kivy__jQuery prototype for later instantiation +__kivy__jQuery.fn.init.prototype = __kivy__jQuery.fn; + +__kivy__jQuery.extend = __kivy__jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !__kivy__jQuery.isFunction(target) ) { + target = {}; + } + + // extend __kivy__jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( __kivy__jQuery.isPlainObject(copy) || (copyIsArray = __kivy__jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && __kivy__jQuery.isArray(src) ? src : []; + + } else { + clone = src && __kivy__jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = __kivy__jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +__kivy__jQuery.extend({ + noConflict: function( deep ) { + if ( window.__kivy__$ === __kivy__jQuery ) { + window.__kivy__$ = __kivy___$; + } + + if ( deep && window.__kivy__jQuery === __kivy__jQuery ) { + window.__kivy__jQuery = ___kivy__jQuery; + } + + return __kivy__jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + __kivy__jQuery.readyWait++; + } else { + __kivy__jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--__kivy__jQuery.readyWait) || (wait !== true && !__kivy__jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( __kivy__jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + __kivy__jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --__kivy__jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ __kivy__jQuery ] ); + + // Trigger any bound ready events + if ( __kivy__jQuery.fn.trigger ) { + __kivy__jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = __kivy__jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( __kivy__jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", __kivy__jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", __kivy__jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return __kivy__jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return __kivy__jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || __kivy__jQuery.type(obj) !== "object" || obj.nodeType || __kivy__jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = __kivy__jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + __kivy__jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + __kivy__jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than __kivy__jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || __kivy__jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = __kivy__jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || __kivy__jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + __kivy__jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof __kivy__jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || __kivy__jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !__kivy__jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || __kivy__jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + __kivy__jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && __kivy__jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of __kivy__jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/__kivy__jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function __kivy__jQuerySub( selector, context ) { + return new __kivy__jQuerySub.fn.init( selector, context ); + } + __kivy__jQuery.extend( true, __kivy__jQuerySub, this ); + __kivy__jQuerySub.superclass = this; + __kivy__jQuerySub.fn = __kivy__jQuerySub.prototype = this(); + __kivy__jQuerySub.fn.constructor = __kivy__jQuerySub; + __kivy__jQuerySub.sub = this.sub; + __kivy__jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof __kivy__jQuery && !(context instanceof __kivy__jQuerySub) ) { + context = __kivy__jQuerySub( context ); + } + + return __kivy__jQuery.fn.init.call( this, selector, context, root__kivy__jQuerySub ); + }; + __kivy__jQuerySub.fn.init.prototype = __kivy__jQuerySub.fn; + var root__kivy__jQuerySub = __kivy__jQuerySub(document); + return __kivy__jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +__kivy__jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = __kivy__jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + __kivy__jQuery.browser[ browserMatch.browser ] = true; + __kivy__jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use __kivy__jQuery.browser.webkit instead +if ( __kivy__jQuery.browser.webkit ) { + __kivy__jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All __kivy__jQuery objects should point back to these +root__kivy__jQuery = __kivy__jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + __kivy__jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + __kivy__jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( __kivy__jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + __kivy__jQuery.ready(); +} + +return __kivy__jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +__kivy__jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = __kivy__jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +__kivy__jQuery.extend({ + + Deferred: function( func ) { + var doneList = __kivy__jQuery.Callbacks( "once memory" ), + failList = __kivy__jQuery.Callbacks( "once memory" ), + progressList = __kivy__jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return __kivy__jQuery.Deferred(function( newDefer ) { + __kivy__jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( __kivy__jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && __kivy__jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && __kivy__jQuery.isFunction( firstParam.promise ) ? + firstParam : + __kivy__jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && __kivy__jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +__kivy__jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + __kivy__jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + __kivy__jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + __kivy__jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +__kivy__jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of __kivy__jQuery on the page + // Non-digits removed to match rinline__kivy__jQuery + expando: "__kivy__jQuery" + ( __kivy__jQuery.fn.__kivy__jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? __kivy__jQuery.cache[ elem[__kivy__jQuery.expando] ] : elem[ __kivy__jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !__kivy__jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = __kivy__jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global __kivy__jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? __kivy__jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++__kivy__jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing __kivy__jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = __kivy__jQuery.noop; + } + } + + // An object can be passed to __kivy__jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = __kivy__jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = __kivy__jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // __kivy__jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ __kivy__jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using __kivy__jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ __kivy__jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !__kivy__jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = __kivy__jQuery.expando, + + isNode = elem.nodeType, + + // See __kivy__jQuery.data for more information + cache = isNode ? __kivy__jQuery.cache : elem, + + // See __kivy__jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !__kivy__jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = __kivy__jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : __kivy__jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See __kivy__jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( __kivy__jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( __kivy__jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return __kivy__jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = __kivy__jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +__kivy__jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = __kivy__jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !__kivy__jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = __kivy__jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + __kivy__jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + __kivy__jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = __kivy__jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = __kivy__jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + __kivy__jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + __kivy__jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + __kivy__jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? __kivy__jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + __kivy__jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && __kivy__jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = __kivy__jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !__kivy__jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !__kivy__jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !__kivy__jQuery._data( elem, queueDataKey ) && + !__kivy__jQuery._data( elem, markDataKey ) ) { + __kivy__jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +__kivy__jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + __kivy__jQuery._data( elem, type, (__kivy__jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (__kivy__jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + __kivy__jQuery._data( elem, key, count ); + } else { + __kivy__jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = __kivy__jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || __kivy__jQuery.isArray(data) ) { + q = __kivy__jQuery._data( elem, type, __kivy__jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = __kivy__jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + __kivy__jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + __kivy__jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + __kivy__jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +__kivy__jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return __kivy__jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = __kivy__jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + __kivy__jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + __kivy__jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = __kivy__jQuery.fx ? __kivy__jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = __kivy__jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = __kivy__jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( __kivy__jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + __kivy__jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + __kivy__jQuery.data( elements[ i ], deferDataKey, __kivy__jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = __kivy__jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +__kivy__jQuery.fn.extend({ + attr: function( name, value ) { + return __kivy__jQuery.access( this, name, value, true, __kivy__jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + __kivy__jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return __kivy__jQuery.access( this, name, value, true, __kivy__jQuery.prop ); + }, + + removeProp: function( name ) { + name = __kivy__jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( j ) { + __kivy__jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = __kivy__jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( j ) { + __kivy__jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = __kivy__jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( i ) { + __kivy__jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = __kivy__jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + __kivy__jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : __kivy__jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = __kivy__jQuery.valHooks[ elem.nodeName.toLowerCase() ] || __kivy__jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = __kivy__jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = __kivy__jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( __kivy__jQuery.isArray( val ) ) { + val = __kivy__jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = __kivy__jQuery.valHooks[ this.nodeName.toLowerCase() ] || __kivy__jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +__kivy__jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (__kivy__jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !__kivy__jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = __kivy__jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return __kivy__jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = __kivy__jQuery.makeArray( value ); + + __kivy__jQuery(elem).find("option").each(function() { + this.selected = __kivy__jQuery.inArray( __kivy__jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in __kivy__jQuery.attrFn ) { + return __kivy__jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return __kivy__jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !__kivy__jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = __kivy__jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + __kivy__jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = __kivy__jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + __kivy__jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + __kivy__jQuery.error( "type property can't be changed" ); + } else if ( !__kivy__jQuery.support.radioValue && value === "radio" && __kivy__jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && __kivy__jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && __kivy__jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !__kivy__jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = __kivy__jQuery.propFix[ name ] || name; + hooks = __kivy__jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +__kivy__jQuery.attrHooks.tabindex = __kivy__jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = __kivy__jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + __kivy__jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = __kivy__jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = __kivy__jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + __kivy__jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + __kivy__jQuery.each([ "width", "height" ], function( i, name ) { + __kivy__jQuery.attrHooks[ name ] = __kivy__jQuery.extend( __kivy__jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + __kivy__jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !__kivy__jQuery.support.hrefNormalized ) { + __kivy__jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + __kivy__jQuery.attrHooks[ name ] = __kivy__jQuery.extend( __kivy__jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !__kivy__jQuery.support.style ) { + __kivy__jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !__kivy__jQuery.support.optSelected ) { + __kivy__jQuery.propHooks.selected = __kivy__jQuery.extend( __kivy__jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !__kivy__jQuery.support.enctype ) { + __kivy__jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !__kivy__jQuery.support.checkOn ) { + __kivy__jQuery.each([ "radio", "checkbox" ], function() { + __kivy__jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +__kivy__jQuery.each([ "radio", "checkbox" ], function() { + __kivy__jQuery.valHooks[ this ] = __kivy__jQuery.extend( __kivy__jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( __kivy__jQuery.isArray( value ) ) { + return ( elem.checked = __kivy__jQuery.inArray( __kivy__jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return __kivy__jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +__kivy__jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = __kivy__jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = __kivy__jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a __kivy__jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof __kivy__jQuery !== "undefined" && (!e || __kivy__jQuery.event.triggered !== e.type) ? + __kivy__jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // __kivy__jQuery(...).bind("mouseover mouseout", fn); + types = __kivy__jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = __kivy__jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = __kivy__jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = __kivy__jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + __kivy__jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = __kivy__jQuery.hasData( elem ) && __kivy__jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = __kivy__jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + __kivy__jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = __kivy__jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + __kivy__jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( __kivy__jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + __kivy__jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + __kivy__jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || __kivy__jQuery.event.customEvent[ type ]) && !__kivy__jQuery.event.global[ type ] ) { + // No __kivy__jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // __kivy__jQuery.Event object + event[ __kivy__jQuery.expando ] ? event : + // Object literal + new __kivy__jQuery.Event( type, event ) : + // Just the event type (string) + new __kivy__jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = __kivy__jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + __kivy__jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? __kivy__jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = __kivy__jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !__kivy__jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( __kivy__jQuery._data( cur, "events" ) || {} )[ event.type ] && __kivy__jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a __kivy__jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && __kivy__jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && __kivy__jQuery.nodeName( elem, "a" )) && __kivy__jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !__kivy__jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + __kivy__jQuery.event.triggered = type; + elem[ type ](); + __kivy__jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable __kivy__jQuery.Event from the native event object + event = __kivy__jQuery.event.fix( event || window.event ); + + var handlers = ( (__kivy__jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed __kivy__jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single __kivy__jQuery object for reuse with .is() + jqcur = __kivy__jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (__kivy__jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ __kivy__jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = __kivy__jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = __kivy__jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: __kivy__jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( __kivy__jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = __kivy__jQuery.extend( + new __kivy__jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + __kivy__jQuery.event.trigger( e, null, elem ); + } else { + __kivy__jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +__kivy__jQuery.event.handle = __kivy__jQuery.event.dispatch; + +__kivy__jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +__kivy__jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof __kivy__jQuery.Event) ) { + return new __kivy__jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + __kivy__jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || __kivy__jQuery.now(); + + // Mark it as fixed + this[ __kivy__jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// __kivy__jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +__kivy__jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +__kivy__jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + __kivy__jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !__kivy__jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !__kivy__jQuery.support.submitBubbles ) { + + __kivy__jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( __kivy__jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + __kivy__jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = __kivy__jQuery.nodeName( elem, "input" ) || __kivy__jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + __kivy__jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + __kivy__jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( __kivy__jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + __kivy__jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !__kivy__jQuery.support.changeBubbles ) { + + __kivy__jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + __kivy__jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + __kivy__jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + __kivy__jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + __kivy__jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + __kivy__jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + __kivy__jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + __kivy__jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !__kivy__jQuery.support.focusinBubbles ) { + __kivy__jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + __kivy__jQuery.event.simulate( fix, event.target, __kivy__jQuery.event.fix( event ), true ); + }; + + __kivy__jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +__kivy__jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + __kivy__jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = __kivy__jQuery.guid++ ); + } + return this.each( function() { + __kivy__jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched __kivy__jQuery.Event + var handleObj = types.handleObj; + __kivy__jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + __kivy__jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + __kivy__jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + __kivy__jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + __kivy__jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return __kivy__jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || __kivy__jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( __kivy__jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + __kivy__jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +__kivy__jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + __kivy__jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( __kivy__jQuery.attrFn ) { + __kivy__jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + __kivy__jQuery.event.fixHooks[ name ] = __kivy__jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + __kivy__jQuery.event.fixHooks[ name ] = __kivy__jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = __kivy__jQuery.attr; +Sizzle.selectors.attrMap = {}; +__kivy__jQuery.find = Sizzle; +__kivy__jQuery.expr = Sizzle.selectors; +__kivy__jQuery.expr[":"] = __kivy__jQuery.expr.filters; +__kivy__jQuery.unique = Sizzle.uniqueSort; +__kivy__jQuery.text = Sizzle.getText; +__kivy__jQuery.isXMLDoc = Sizzle.isXML; +__kivy__jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = __kivy__jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +__kivy__jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return __kivy__jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( __kivy__jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + __kivy__jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = __kivy__jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( __kivy__jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + __kivy__jQuery( selector, this.context ).index( this[0] ) >= 0 : + __kivy__jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of __kivy__jQuery 1.7) + if ( __kivy__jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( __kivy__jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + __kivy__jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : __kivy__jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? __kivy__jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return __kivy__jQuery.inArray( this[0], __kivy__jQuery( elem ) ); + } + + // Locate the position of the desired element + return __kivy__jQuery.inArray( + // If it receives a __kivy__jQuery object, the first element is used + elem.__kivy__jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + __kivy__jQuery( selector, context ) : + __kivy__jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = __kivy__jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + __kivy__jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +__kivy__jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return __kivy__jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return __kivy__jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return __kivy__jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return __kivy__jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return __kivy__jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return __kivy__jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return __kivy__jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return __kivy__jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + __kivy__jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + __kivy__jQuery.fn[ name ] = function( until, selector ) { + var ret = __kivy__jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = __kivy__jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? __kivy__jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +__kivy__jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + __kivy__jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + __kivy__jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !__kivy__jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( __kivy__jQuery.isFunction( qualifier ) ) { + return __kivy__jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return __kivy__jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = __kivy__jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return __kivy__jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = __kivy__jQuery.filter( qualifier, filtered ); + } + } + + return __kivy__jQuery.grep(elements, function( elem, i ) { + return ( __kivy__jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinline__kivy__jQuery = / __kivy__jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + +Some <select> element from JIRA:
+(click submit to test the post data sent)

+ + +
+ + + + + +
+ +

With Fixed as "selected":

+ + + +

Add new <select> element dynamically on a page:
+ (select boxes are checked every second on a page,
+ you should see a normal select element transforming
+ into js select box a moment after you click the button)

+ + + + + +
+ +

+ + + +

Test interaction with other webpages that already use some other
+ javascript boxes library. +

+ +

These links need to be opened in the kivy_.py example:

+ + + +

Some libraries that are not well-designed will display
+ the select element twice, take a look at this for example:

+ + + http://adam.co/lab/jquery/customselect/ (open in kivy_.py example) + +

+Although, it will still be functional, just with a display glitch. +

+ +

The following code was added to the + SelectBox library to transform <select> element into + js box only if it's visible on a webpage:

+ +
+    // This should fix interaction with other js boxes libraries,
+    // so that the select element does not appear twice.
+    if (!$(select).is(":visible")) {
+        return;
+    }
+
+ +Also this code gives one second to other select box libraries
+to do their stuff, before we start ours: + +
+    __kivy__jQuery(document).ready(function() {
+    // Transform select elements only after a second,
+    // this will give time other select boxes libraries
+    // included on a webpage to their stuff first.
+    window.setInterval(function(){
+        __kivy__jQuery(document).ready(function() { 
+            __kivy__jQuery("select").__kivy__selectBox(); 
+        });
+    }, 1000);
+});
+
+ + + + \ No newline at end of file diff --git a/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/readme.md b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/readme.md new file mode 100755 index 00000000..ad45aa7f --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/kivy-select-boxes/readme.md @@ -0,0 +1,156 @@ +# jQuery selectBox: A styleable replacement for SELECT elements + +_Licensed under the MIT license: http://opensource.org/licenses/MIT_ + +## Features + +* Supports OPTGROUPS +* Supports standard dropdown controls +* Supports multi-select controls (i.e. multiple="multiple") +* Supports inline controls (i.e. size="5") +* Fully accessible via keyboard +* Shift + click (or shift + enter) to select a range of options in multi-select controls +* Type to search when the control has focus +* Auto-height based on the size attribute (to use, omit the height property in your CSS!) +* Tested in IE7-IE9, Firefox 3-4, recent WebKit browsers, and Opera + + +## Usage + +Link to the JS file: + +```html + +``` + +Add the CSS file (or append contents to your own stylesheet): + +```html + +``` + +To initialize: + +```javascript +// default +$('select').selectBox(); + +// or with custom settings +$('select').selectBox({ + mobile: true, + menuSpeed: 'fast' +}); +``` + +## Settings + +| Key | Default | Values | Description | +| ---------------|:-------------:|---------------------------:|-------------------------------------------------:| +| mobile | `false` | Boolean | Disables the widget for mobile devices | +| menuTransition | `default` | `default`, `slide`, `fade` | The show/hide transition for dropdown menus | +| menuSpeed | `normal` | `slow`, `normal`, `fast` | The show/hide transition speed | +| loopOptions | `false` | Boolean | Flag to allow arrow keys to loop through options | + + +To specify settings after the init, use this syntax: + +```javascript +$('select').selectBox('settings', {settingName: value, ... }); +``` + +## Methods + +To call a method use this syntax: + +```javascript +$('select').selectBox('methodName', [option]); +``` + +### Available methods + + +| Key | Description | +| ---------------|-----------------------------------------------------------------------------------------------| +| create | Creates the control (default) | +| destroy | Destroys the selectBox control and reverts back to the original form control | +| disable | Disables the control (i.e. disabled="disabled") | +| enable | Enables the control | +| value | If passed with a value, sets the control to that value; otherwise returns the current value | +| options | If passed either a string of HTML or a JSON object, replaces the existing options; otherwise Returns the options container element as a jQuery object | +| control | Returns the selectBox control element (an anchor tag) for working with directly | +| refresh | Updates the selectBox control's options based on the original controls options | +| instance | Returns the SelectBox instance, where you have more methods available (only in v1.2.0-dev | + | available) as in the `SelectBox` class below. | + +## API `SelectBox` + +You can instantiate the selectBox also through a classic OOP way: + +```javascript +var selectBox = new SelectBox($('#mySelectBox'), settings = {}); +selectBox.showMenu(); +``` + +The public methods are: + +```javascript +refresh() +destroy() +disable() +enable() + +getLabelClass() +getLabelText() +getSelectElement() +getOptions(String type = 'inline'|'dropdown') + +hideMenus() +showMenu() + +setLabel() +setOptions(Object options) +setValue(String value) + +removeHover(HTMLElement li) +addHover(HTMLElement li) + +disableSelection(HTMLElement selector) +generateOptions(jQuery self, jQuery options) +handleKeyDown(event) +handleKeyPress(event) +init(options) +keepOptionInView(jQuery li, Boolean center) +refresh() +removeHover(HTMLElement li) +selectOption(HTMLElement li, event) +``` + +## Events + +Events are fired on the original select element. You can bind events like this: + +```javascript +$('select').selectBox().change(function () { + alert($(this).val()); +}); +``` + +### Available events + +| Key | Description | +| ---------------|-----------------------------------------------------------------------------------------------| +| focus | Fired when the control gains focus | +| blur | Fired when the control loses focus | +| change | Fired when the value of a control changes | +| beforeopen | Fired before a dropdown menu opens (cancelable) | +| open | Fired after a dropdown menu opens (not cancelable) | +| beforeclose | Fired before a dropdown menu closes (cancelable) | +| close | Fired after a dropdown menu closes (not cancelable) | + +### Known Issues + +* The blur and focus callbacks are not very reliable in IE7. The change callback works fine. + +## Credits + +Original plugin by Cory LaViska of A Beautiful Site, LLC. (http://www.abeautifulsite.net/) \ No newline at end of file diff --git a/cefpython/cef3/linux/binaries_32bit/kivy_.py b/cefpython/cef3/linux/binaries_32bit/kivy_.py new file mode 100644 index 00000000..e366e557 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/kivy_.py @@ -0,0 +1,678 @@ +# An example of embedding CEF browser in the Kivy framework. +# The browser is embedded using off-screen rendering mode. + +# Tested using Kivy 1.7.2 stable on Ubuntu 12.04 64-bit. + +# In this example kivy-lang is used to declare the layout which +# contains two buttons (back, forward) and the browser view. + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname( + os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +from kivy.app import App +from kivy.uix.widget import Widget +from kivy.graphics import Color, Rectangle, GraphicException +from kivy.clock import Clock +from kivy.graphics.texture import Texture +from kivy.core.window import Window +from kivy.lang import Builder +from kivy.uix.boxlayout import BoxLayout +from kivy.base import EventLoop + +####Kivy APP #### +Builder.load_string(""" + +: + orientation: 'vertical' + BoxLayout: + size_hint_y: None + width: 80 + Button: + text: "Back" + on_press: browser.go_back() + Button: + text: "Forward" + on_press: browser.go_forward() + CefBrowser: + id: browser + +""") + + + +class BrowserLayout(BoxLayout): + + def __init__(self, **kwargs): + super(BrowserLayout, self).__init__(**kwargs) + + + +class CefBrowser(Widget): + + # Keyboard mode: "global" or "local". + # 1. Global mode forwards keys to CEF all the time. + # 2. Local mode forwards keys to CEF only when an editable + # control is focused (input type=text|password or textarea). + keyboard_mode = "global" + + '''Represent a browser widget for kivy, which can be used like a normal widget. + ''' + def __init__(self, start_url='http://www.google.com/', **kwargs): + super(CefBrowser, self).__init__(**kwargs) + + self.start_url = start_url + + #Workaround for flexible size: + #start browser when the height has changed (done by layout) + #This has to be done like this because I wasn't able to change + #the texture size + #until runtime without core-dump. + self.bind(size = self.size_changed) + + + starting = True + def size_changed(self, *kwargs): + '''When the height of the cefbrowser widget got changed, create the browser + ''' + if self.starting: + if self.height != 100: + self.start_cef() + self.starting = False + else: + self.texture = Texture.create( + size=self.size, colorfmt='rgba', bufferfmt='ubyte') + self.texture.flip_vertical() + with self.canvas: + Color(1, 1, 1) + # This will cause segmentation fault: + # | self.rect = Rectangle(size=self.size, texture=self.texture) + # Update only the size: + self.rect.size = self.size + self.browser.WasResized() + + + def _cef_mes(self, *kwargs): + '''Get called every frame. + ''' + cefpython.MessageLoopWork() + + + def _update_rect(self, *kwargs): + '''Get called whenever the texture got updated. + => we need to reset the texture for the rectangle + ''' + self.rect.texture = self.texture + + + def start_cef(self): + '''Starts CEF. + ''' + # create texture & add it to canvas + self.texture = Texture.create( + size=self.size, colorfmt='rgba', bufferfmt='ubyte') + self.texture.flip_vertical() + with self.canvas: + Color(1, 1, 1) + self.rect = Rectangle(size=self.size, texture=self.texture) + + #configure cef + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": "debug.log", + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % (cefpython.GetModuleDirectory(), "subprocess")} + + #start idle + Clock.schedule_interval(self._cef_mes, 0) + + #init CEF + cefpython.Initialize(settings) + + #WindowInfo offscreen flag + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsOffscreen(0) + + #Create Broswer and naviagte to empty page <= OnPaint won't get called yet + browserSettings = {} + # The render handler callbacks are not yet set, thus an + # error report will be thrown in the console (when release + # DCHECKS are enabled), however don't worry, it is harmless. + # This is happening because calling GetViewRect will return + # false. That's why it is initially navigating to "about:blank". + # Later, a real url will be loaded using the LoadUrl() method + # and the GetViewRect will be called again. This time the render + # handler callbacks will be available, it will work fine from + # this point. + # -- + # Do not use "about:blank" as navigateUrl - this will cause + # the GoBack() and GoForward() methods to not work. + self.browser = cefpython.CreateBrowserSync(windowInfo, browserSettings, + navigateUrl=self.start_url) + + #set focus + self.browser.SendFocusEvent(True) + + self._client_handler = ClientHandler(self) + self.browser.SetClientHandler(self._client_handler) + self.set_js_bindings() + + #Call WasResized() => force cef to call GetViewRect() and OnPaint afterwards + self.browser.WasResized() + + # The browserWidget instance is required in OnLoadingStateChange(). + self.browser.SetUserData("browserWidget", self) + + if self.keyboard_mode == "global": + self.request_keyboard() + + # Clock.schedule_once(self.change_url, 5) + + + _client_handler = None + _js_bindings = None + + def set_js_bindings(self): + if not self._js_bindings: + self._js_bindings = cefpython.JavascriptBindings( + bindToFrames=True, bindToPopups=True) + self._js_bindings.SetFunction("__kivy__request_keyboard", + self.request_keyboard) + self._js_bindings.SetFunction("__kivy__release_keyboard", + self.release_keyboard) + self.browser.SetJavascriptBindings(self._js_bindings) + + + def change_url(self, *kwargs): + # Doing a javascript redirect instead of Navigate() + # solves the js bindings error. The url here need to + # be preceded with "http://". Calling StopLoad() + # might be a good idea before making the js navigation. + + self.browser.StopLoad() + self.browser.GetMainFrame().ExecuteJavascript( + "window.location='http://www.youtube.com/'") + + # Do not use Navigate() or GetMainFrame()->LoadURL(), + # as it causes the js bindings to be removed. There is + # a bug in CEF, that happens after a call to Navigate(). + # The OnBrowserDestroyed() callback is fired and causes + # the js bindings to be removed. See this topic for more + # details: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=11009 + + # OFF: + # | self.browser.Navigate("http://www.youtube.com/") + + _keyboard = None + + def request_keyboard(self): + print("request_keyboard()") + self._keyboard = EventLoop.window.request_keyboard( + self.release_keyboard, self) + self._keyboard.bind(on_key_down=self.on_key_down) + self._keyboard.bind(on_key_up=self.on_key_up) + self.is_shift1 = False + self.is_shift2 = False + self.is_ctrl1 = False + self.is_ctrl2 = False + self.is_alt1 = False + self.is_alt2 = False + # Not sure if it is still required to send the focus + # (some earlier bug), but it shouldn't hurt to call it. + self.browser.SendFocusEvent(True) + + + def release_keyboard(self): + # When using local keyboard mode, do all the request + # and releases of the keyboard through js bindings, + # otherwise some focus problems arise. + self.is_shift1 = False + self.is_shift2 = False + self.is_ctrl1 = False + self.is_ctrl2 = False + self.is_alt1 = False + self.is_alt2 = False + if not self._keyboard: + return + print("release_keyboard()") + self._keyboard.unbind(on_key_down=self.on_key_down) + self._keyboard.unbind(on_key_up=self.on_key_up) + self._keyboard.release() + + # Kivy does not provide modifiers in on_key_up, but these + # must be sent to CEF as well. + is_shift1 = False + is_shift2 = False + is_ctrl1 = False + is_ctrl2 = False + is_alt1 = False + is_alt2 = False + + def on_key_down(self, keyboard, keycode, text, modifiers): + # Notes: + # - right alt modifier is not sent by Kivy through modifiers param. + # print("on_key_down(): keycode = %s, text = %s, modifiers = %s" % ( + # keycode, text, modifiers)) + if keycode[0] == 27: + # On escape release the keyboard, see the injected + # javascript in OnLoadStart(). + self.browser.GetFocusedFrame().ExecuteJavascript( + "__kivy__on_escape()") + return + cefModifiers = cefpython.EVENTFLAG_NONE + if "shift" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_SHIFT_DOWN + if "ctrl" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_CONTROL_DOWN + if "alt" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_ALT_DOWN + if "capslock" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_CAPS_LOCK_ON + # print("on_key_down(): cefModifiers = %s" % cefModifiers) + cef_keycode = self.translate_to_cef_keycode(keycode[0]) + keyEvent = { + "type": cefpython.KEYEVENT_RAWKEYDOWN, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("keydown keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + if keycode[0] == 304: + self.is_shift1 = True + elif keycode[0] == 303: + self.is_shift2 = True + elif keycode[0] == 306: + self.is_ctrl1 = True + elif keycode[0] == 305: + self.is_ctrl2 = True + elif keycode[0] == 308: + self.is_alt1 = True + elif keycode[0] == 313: + self.is_alt2 = True + + + def on_key_up(self, keyboard, keycode): + # print("on_key_up(): keycode = %s" % (keycode,)) + cefModifiers = cefpython.EVENTFLAG_NONE + if self.is_shift1 or self.is_shift2: + cefModifiers |= cefpython.EVENTFLAG_SHIFT_DOWN + if self.is_ctrl1 or self.is_ctrl2: + cefModifiers |= cefpython.EVENTFLAG_CONTROL_DOWN + if self.is_alt1: + cefModifiers |= cefpython.EVENTFLAG_ALT_DOWN + # Capslock todo. + cef_keycode = self.translate_to_cef_keycode(keycode[0]) + keyEvent = { + "type": cefpython.KEYEVENT_KEYUP, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("keyup keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + keyEvent = { + "type": cefpython.KEYEVENT_CHAR, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("char keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + if keycode[0] == 304: + self.is_shift1 = False + elif keycode[0] == 303: + self.is_shift2 = False + elif keycode[0] == 306: + self.is_ctrl1 = False + elif keycode[0] == 305: + self.is_ctrl2 = False + elif keycode[0] == 308: + self.is_alt1 = False + elif keycode[0] == 313: + self.is_alt2 = False + + + def translate_to_cef_keycode(self, keycode): + # TODO: this works on Linux, but on Windows the key + # mappings will probably be different. + # TODO: what if the Kivy keyboard layout is changed + # from qwerty to azerty? (F1 > options..) + cef_keycode = keycode + if self.is_alt2: + # The key mappings here for right alt were tested + # with the utf-8 charset on a webpage. If the charset + # is different there is a chance they won't work correctly. + alt2_map = { + # tilde + "96":172, + # 0-9 (48..57) + "48":125, "49":185, "50":178, "51":179, "52":188, + "53":189, "54":190, "55":123, "56":91, "57":93, + # minus + "45":92, + # a-z (97..122) + "97":433, "98":2771, "99":486, "100":240, "101":490, + "102":496, "103":959, "104":689, "105":2301, "106":65121, + "107":930, "108":435, "109":181, "110":497, "111":243, + "112":254, "113":64, "114":182, "115":438, "116":956, + "117":2302, "118":2770, "119":435, "120":444, "121":2299, + "122":447, + } + if str(keycode) in alt2_map: + cef_keycode = alt2_map[str(keycode)] + else: + print("Kivy to CEF key mapping not found (right alt), " \ + "key code = %s" % keycode) + shift_alt2_map = { + # tilde + "96":172, + # 0-9 (48..57) + "48":176, "49":161, "50":2755, "51":163, "52":36, + "53":2756, "54":2757, "55":2758, "56":2761, "57":177, + # minus + "45":191, + # A-Z (97..122) + "97":417, "98":2769, "99":454, "100":208, "101":458, + "102":170, "103":957, "104":673, "105":697, "106":65122, + "107":38, "108":419, "109":186, "110":465, "111":211, + "112":222, "113":2009, "114":174, "115":422, "116":940, + "117":2300, "118":2768, "119":419, "120":428, "121":165, + "122":431, + # special: <>? :" {} + "44":215, "46":247, "47":65110, + "59":65113, "39":65114, + "91":65112, "93":65108, + } + if self.is_shift1 or self.is_shift2: + if str(keycode) in shift_alt2_map: + cef_keycode = shift_alt2_map[str(keycode)] + else: + print("Kivy to CEF key mapping not found " \ + "(shift + right alt), key code = %s" % keycode) + elif self.is_shift1 or self.is_shift2: + shift_map = { + # tilde + "96":126, + # 0-9 (48..57) + "48":41, "49":33, "50":64, "51":35, "52":36, "53":37, + "54":94, "55":38, "56":42, "57":40, + # minus, plus + "45":95, "61":43, + # a-z (97..122) + "97":65, "98":66, "99":67, "100":68, "101":69, "102":70, + "103":71, "104":72, "105":73, "106":74, "107":75, "108":76, + "109":77, "110":78, "111":79, "112":80, "113":81, "114":82, + "115":83, "116":84, "117":85, "118":86, "119":87, "120":88, + "121":89, "122":90, + # special: <>? :" {} + "44":60, "46":62, "47":63, + "59":58, "39":34, + "91":123, "93":125, + } + if str(keycode) in shift_map: + cef_keycode = shift_map[str(keycode)] + # Other keys: + other_keys_map = { + # Escape + "27":65307, + # F1-F12 + "282":65470, "283":65471, "284":65472, "285":65473, + "286":65474, "287":65475, "288":65476, "289":65477, + "290":65478, "291":65479, "292":65480, "293":65481, + # Tab + "9":65289, + # Left Shift, Right Shift + "304":65505, "303":65506, + # Left Ctrl, Right Ctrl + "306":65507, "305": 65508, + # Left Alt, Right Alt + "308":65513, "313":65027, + # Backspace + "8":65288, + # Enter + "13":65293, + # PrScr, ScrLck, Pause + "316":65377, "302":65300, "19":65299, + # Insert, Delete, + # Home, End, + # Pgup, Pgdn + "277":65379, "127":65535, + "278":65360, "279":65367, + "280":65365, "281":65366, + # Arrows (left, up, right, down) + "276":65361, "273":65362, "275":65363, "274":65364, + } + if str(keycode) in other_keys_map: + cef_keycode = other_keys_map[str(keycode)] + return cef_keycode + + + def go_forward(self): + '''Going to forward in browser history + ''' + print "go forward" + self.browser.GoForward() + + + def go_back(self): + '''Going back in browser history + ''' + print "go back" + self.browser.GoBack() + + + def on_touch_down(self, touch, *kwargs): + if not self.collide_point(*touch.pos): + return + touch.grab(self) + + y = self.height-touch.pos[1] + self.browser.SendMouseClickEvent(touch.x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=False, clickCount=1) + + + def on_touch_move(self, touch, *kwargs): + if touch.grab_current is not self: + return + + y = self.height-touch.pos[1] + self.browser.SendMouseMoveEvent(touch.x, y, mouseLeave=False) + + + def on_touch_up(self, touch, *kwargs): + if touch.grab_current is not self: + return + + y = self.height-touch.pos[1] + self.browser.SendMouseClickEvent(touch.x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=True, clickCount=1) + touch.ungrab(self) + + +class ClientHandler: + + def __init__(self, browserWidget): + self.browserWidget = browserWidget + + + def _fix_select_boxes(self, frame): + # This is just a temporary fix, until proper Popup widgets + # painting is implemented (PET_POPUP in OnPaint). Currently + # there is no way to obtain a native window handle (GtkWindow + # pointer) in Kivy, and this may cause things like context menus, + # select boxes and plugins not to display correctly. Although, + # this needs to be tested. The popup widget buffers are + # available in a separate paint buffer, so they could positioned + # freely so that it doesn't go out of the window. So the native + # window handle might not necessarily be required to make it work + # in most cases (99.9%). Though, this still needs testing to confirm. + # -- + # See this topic on the CEF Forum regarding the NULL window handle: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10851 + # -- + # See also a related topic on the Kivy-users group: + # https://groups.google.com/d/topic/kivy-users/WdEQyHI5vTs/discussion + # -- + # The javascript select boxes library used: + # http://marcj.github.io/jquery-selectBox/ + # -- + # Cannot use "file://" urls to load local resources, error: + # | Not allowed to load local resource + print("_fix_select_boxes()") + resources_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "kivy-select-boxes") + if not os.path.exists(resources_dir): + print("The kivy-select-boxes directory does not exist, " \ + "select boxes fix won't be applied.") + return + js_file = os.path.join(resources_dir, "kivy-selectBox.js") + js_content = "" + with open(js_file, "r") as myfile: + js_content = myfile.read() + css_file = os.path.join(resources_dir, "kivy-selectBox.css") + css_content = "" + with open(css_file, "r") as myfile: + css_content = myfile.read() + css_content = css_content.replace("\r", "") + css_content = css_content.replace("\n", "") + jsCode = """ + %(js_content)s + var __kivy_temp_head = document.getElementsByTagName('head')[0]; + var __kivy_temp_style = document.createElement('style'); + __kivy_temp_style.type = 'text/css'; + __kivy_temp_style.appendChild(document.createTextNode("%(css_content)s")); + __kivy_temp_head.appendChild(__kivy_temp_style); + """ % locals() + frame.ExecuteJavascript(jsCode, + "kivy_.py > ClientHandler > OnLoadStart > _fix_select_boxes()") + + + def OnLoadStart(self, browser, frame): + self._fix_select_boxes(frame); + browserWidget = browser.GetUserData("browserWidget") + if browserWidget and browserWidget.keyboard_mode == "local": + print("OnLoadStart(): injecting focus listeners for text controls") + # The logic is similar to the one found in kivy-berkelium: + # https://github.com/kivy/kivy-berkelium/blob/master/berkelium/__init__.py + jsCode = """ + var __kivy__keyboard_requested = false; + function __kivy__keyboard_interval() { + var element = document.activeElement; + if (!element) { + return; + } + var tag = element.tagName; + var type = element.type; + if (tag == "INPUT" && (type == "" || type == "text" + || type == "password") || tag == "TEXTAREA") { + if (!__kivy__keyboard_requested) { + __kivy__request_keyboard(); + __kivy__keyboard_requested = true; + } + return; + } + if (__kivy__keyboard_requested) { + __kivy__release_keyboard(); + __kivy__keyboard_requested = false; + } + } + function __kivy__on_escape() { + if (document.activeElement) { + document.activeElement.blur(); + } + if (__kivy__keyboard_requested) { + __kivy__release_keyboard(); + __kivy__keyboard_requested = false; + } + } + setInterval(__kivy__keyboard_interval, 100); + """ + frame.ExecuteJavascript(jsCode, + "kivy_.py > ClientHandler > OnLoadStart") + + + def OnLoadEnd(self, browser, frame, httpStatusCode): + # Browser lost its focus after the LoadURL() and the + # OnBrowserDestroyed() callback bug. When keyboard mode + # is local the fix is in the request_keyboard() method. + # Call it from OnLoadEnd only when keyboard mode is global. + browserWidget = browser.GetUserData("browserWidget") + if browserWidget and browserWidget.keyboard_mode == "global": + browser.SendFocusEvent(True) + + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("OnLoadingStateChange(): isLoading = %s" % isLoading) + browserWidget = browser.GetUserData("browserWidget") + + + def OnPaint(self, browser, paintElementType, dirtyRects, buffer, width, + height): + # print "OnPaint()" + if paintElementType != cefpython.PET_VIEW: + print "Popups aren't implemented yet" + return + + #update buffer + buffer = buffer.GetString(mode="bgra", origin="top-left") + + #update texture of canvas rectangle + self.browserWidget.texture.blit_buffer(buffer, colorfmt='bgra', + bufferfmt='ubyte') + self.browserWidget._update_rect() + + return True + + + def GetViewRect(self, browser, rect): + width, height = self.browserWidget.texture.size + rect.append(0) + rect.append(0) + rect.append(width) + rect.append(height) + # print("GetViewRect(): %s x %s" % (width, height)) + return True + + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + suppressMessage[0] = True + return False + + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + callback.Continue(allow=True, userInput="") + return True + + +if __name__ == '__main__': + class CefBrowserApp(App): + def build(self): + return BrowserLayout() + CefBrowserApp().run() + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_32bit/prism.css b/cefpython/cef3/linux/binaries_32bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/linux/binaries_32bit/prism.js b/cefpython/cef3/linux/binaries_32bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/linux/binaries_32bit/pygtk_.py b/cefpython/cef3/linux/binaries_32bit/pygtk_.py new file mode 100644 index 00000000..e3afae4f --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/pygtk_.py @@ -0,0 +1,200 @@ +# An example of embedding the CEF browser in PyGTK on Linux. +# Tested with GTK "2.24.10". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import re + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pygtk_.py]: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + vbox = None + + def __init__(self): + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=800, height=600) + self.mainWindow.set_title('PyGTK CEF example') + self.mainWindow.realize() + + self.vbox = gtk.VBox(False, 0) + self.vbox.pack_start(self.CreateMenu(), False, False, 0) + self.mainWindow.add(self.vbox) + + m = re.search("GtkVBox at 0x(\w+)", str(self.vbox)) + hexID = m.group(1) + windowID = int(hexID, 16) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + browserSettings={}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + self.vbox.show() + self.mainWindow.show() + gobject.timeout_add(10, self.OnTimer) + + def CreateMenu(self): + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + + about = gtk.MenuItem('About') + about.show() + aboutmenu = gtk.Menu() + item = gtk.MenuItem('CEF Python') + aboutmenu.append(item) + item.show() + about.set_submenu(aboutmenu) + + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + + return menubar + + def OnWidgetClick(self, widget, data): + self.mainWindow.get_window().focus() + + def OnTimer(self): + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + # This function is currently not called by any of code, + # but if you would like for browser to have automatic focus + # add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + self.browser.SetFocus(True) + + def OnExit(self, widget, data=None): + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + version = '.'.join(map(str, list(gtk.gtk_version))) + print('[pygtk_.py] GTK version: %s' % version) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable + "release_dcheck_enabled": True, # Enable only when debugging + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + cefpython.Initialize(settings) + + gobject.threads_init() # Timer for the message loop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_32bit/pyqt.py b/cefpython/cef3/linux/binaries_32bit/pyqt.py new file mode 100644 index 00000000..a786470d --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/pyqt.py @@ -0,0 +1,239 @@ +# An example of embedding the CEF browser in a PyQt4 application. +# Tested with PyQt "4.9.1". +# Command for installing PyQt4: "sudo apt-get install python-qt4". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +from PyQt4 import QtGui +from PyQt4 import QtCore + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pyqt.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PyQT CEF 3 example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + # cefpython.WindowUtils.OnSetFocus( + # int(self.centralWidget().winId()), 0, 0, 0) + pass + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QX11EmbedContainer): + browser = None + plug = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + + # QX11EmbedContainer provides an X11 window. The CEF + # browser can be embedded only by providing a GtkWidget + # pointer. So we're embedding a GtkPlug inside the X11 + # window. In latest CEF trunk it is possible to embed + # the CEF browser by providing X11 window id. So it will + # be possible to remove the GTK dependency from CEF + # Python in the future. + gtkPlugPtr = cefpython.WindowUtils.gtk_plug_new(\ + int(self.winId())) + print("[pyqt.py] MainFrame: GDK Native Window id: "+str(self.winId())) + print("[pyqt.py] MainFrame: GTK Plug ptr: "+str(gtkPlugPtr)) + + """ + Embedding GtkPlug is also possible with the pygtk module. + --------------------------------------------------------- + self.plug = gtk.Plug(self.winId()) + import re + m = re.search("GtkPlug at 0x(\w+)", str(self.plug)) + hexId = m.group(1) + gtkPlugPtr = int(hexId, 16) + ... + plug.show() + self.show() + --------------------------------------------------------- + """ + + windowInfo = cefpython.WindowInfo() + # Need to pass to CEF the GtkWidget* pointer + windowInfo.SetAsChild(gtkPlugPtr) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + cefpython.WindowUtils.gtk_widget_show(gtkPlugPtr) + self.show() + + def moveEvent(self, event): + # cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + pass + + def resizeEvent(self, event): + # cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + pass + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() + # returns False. + # But there is a bug in Qt, hasPendingEvents() returns + # always true. + # (The behavior described above was tested on Windows + # with pyqt 4.8, maybe this is not true anymore, + # test it TODO) + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to + # MessageLoopWork() should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("[pyqt.py] PyQt version: %s" % QtCore.PYQT_VERSION_STR) + print("[pyqt.py] QtCore version: %s" % QtCore.qVersion()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "enable-media-stream": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_32bit/wxpython-response.py b/cefpython/cef3/linux/binaries_32bit/wxpython-response.py new file mode 100644 index 00000000..9af202fd --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/wxpython-response.py @@ -0,0 +1,453 @@ +# An example of embedding CEF browser in wxPython on Linux. +# Tested with wxPython 2.8.12.1 (gtk2-unicode). +# To install wxPython type "sudo apt-get install python-wxtools". + +# This example implements a custom "_OnResourceResponse" callback +# that emulates reading response by utilizing Resourcehandler +# and WebRequest. + +FIX_ENCODING_BUG = True +BROWSER_DEFAULT_ENCODING = "utf-8" + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import shutil + +class ClientHandler: + + # RequestHandler.GetResourceHandler() + def GetResourceHandler(self, browser, frame, request): + # Called on the IO thread before a resource is loaded. + # To allow the resource to load normally return None. + print("GetResourceHandler(): url = %s" % request.GetUrl()) + resHandler = ResourceHandler() + resHandler._clientHandler = self + resHandler._browser = browser + resHandler._frame = frame + resHandler._request = request + self._AddStrongReference(resHandler) + return resHandler + + def _OnResourceResponse(self, browser, frame, request, requestStatus, + requestError, response, data): + # This callback is emulated through ResourceHandler + # and WebRequest. Real "OnResourceResponse" is not yet + # available in CEF 3 (as of CEF revision 1450). See + # issue 515 in the CEF Issue Tracker: + # https://code.google.com/p/chromiumembedded/issues/detail?id=515 + # ---- + # requestStatus => cefpython.WebRequest.Status + # {"Unknown", "Success", "Pending", "Canceled", "Failed"} + # For "file://" requests the status will be "Unknown". + # requestError => see the NetworkError wiki page + # response.GetStatus() => http status code + print("_OnResourceResponse()") + print("data length = %s" % len(data)) + # Return the new data - you can modify it. + if request.GetUrl().startswith("file://") \ + and request.GetUrl().endswith("example.html"): + data = "This text was inserted through " \ + + "_OnResourceResponse()
" + data + # Non-english characters are not displaying correctly. + # This is a bug in CEF. A quick fix is to get the charset + # from response headers and insert into + # the html page. + # Bug reported on the CEF C++ Forum: + # http://www.magpcss.org/ceforum/viewtopic.php?p=18401#p18401 + if FIX_ENCODING_BUG: + contentType = response.GetHeader("Content-Type") + if contentType: + contentType = contentType.lower() + isHtml = False + headerCharset = "" + if contentType and "text/html" in contentType: + isHtml = True + if contentType and "charset" in contentType: + match = re.search(r"charset\s*=\s*([^\s]+)", contentType) + if match and match.group(1): + headerCharset = match.group(1).lower() + if isHtml and headerCharset \ + and headerCharset != BROWSER_DEFAULT_ENCODING.lower(): + if not re.search(r"]+charset\s*=", data, \ + re.IGNORECASE): + # Only apply the fix if there is no + # available on a page. + data = ("" % headerCharset) + data + return data + + # A strong reference to ResourceHandler must be kept + # during the request. Some helper functions for that. + # 1. Add reference in GetResourceHandler() + # 2. Release reference in ResourceHandler.ReadResponse() + # after request is completed. + + _resourceHandlers = {} + _resourceHandlerMaxId = 0 + + def _AddStrongReference(self, resHandler): + self._resourceHandlerMaxId += 1 + resHandler._resourceHandlerId = self._resourceHandlerMaxId + self._resourceHandlers[resHandler._resourceHandlerId] = resHandler + + def _ReleaseStrongReference(self, resHandler): + if resHandler._resourceHandlerId in self._resourceHandlers: + del self._resourceHandlers[resHandler._resourceHandlerId] + else: + print("_ReleaseStrongReference() FAILED: resource handler " \ + "not found, id = %s" % (resHandler._resourceHandlerId)) + +class ResourceHandler: + + # The methods of this class will always be called + # on the IO thread. + + _resourceHandlerId = None + _clientHandler = None + _browser = None + _frame = None + _request = None + _responseHeadersReadyCallback = None + _webRequest = None + _webRequestClient = None + _offsetRead = 0 + + def ProcessRequest(self, request, callback): + print("ProcessRequest()") + # 1. Start the request using WebRequest + # 2. Return True to handle the request + # 3. Once response headers are ready call + # callback.Continue() + self._responseHeadersReadyCallback = callback + self._webRequestClient = WebRequestClient() + self._webRequestClient._resourceHandler = self + # Need to set AllowCacheCredentials and AllowCookies for + # the cookies to work during POST requests (Issue 127). + # To skip cache set the SkipCache request flag. + request.SetFlags(cefpython.Request.Flags["AllowCachedCredentials"]\ + | cefpython.Request.Flags["AllowCookies"]) + # A strong reference to the WebRequest object must kept. + self._webRequest = cefpython.WebRequest.Create( + request, self._webRequestClient) + return True + + def GetResponseHeaders(self, response, responseLengthOut, redirectUrlOut): + print("GetResponseHeaders()") + # 1. If the response length is not known set + # responseLengthOut[0] to -1 and ReadResponse() + # will be called until it returns False. + # 2. If the response length is known set + # responseLengthOut[0] to a positive value + # and ReadResponse() will be called until it + # returns False or the specified number of bytes + # have been read. + # 3. Use the |response| object to set the mime type, + # http status code and other optional header values. + # 4. To redirect the request to a new URL set + # redirectUrlOut[0] to the new url. + assert self._webRequestClient._response, "Response object empty" + wrcResponse = self._webRequestClient._response + response.SetStatus(wrcResponse.GetStatus()) + response.SetStatusText(wrcResponse.GetStatusText()) + response.SetMimeType(wrcResponse.GetMimeType()) + if wrcResponse.GetHeaderMultimap(): + response.SetHeaderMultimap(wrcResponse.GetHeaderMultimap()) + print("headers: ") + print(wrcResponse.GetHeaderMap()) + responseLengthOut[0] = self._webRequestClient._dataLength + if not responseLengthOut[0]: + # Probably a cached page? Or a redirect? + pass + + def ReadResponse(self, dataOut, bytesToRead, bytesReadOut, callback): + # print("ReadResponse()") + # 1. If data is available immediately copy up to + # bytesToRead bytes into dataOut[0], set + # bytesReadOut[0] to the number of bytes copied, + # and return true. + # 2. To read the data at a later time set + # bytesReadOut[0] to 0, return true and call + # callback.Continue() when the data is available. + # 3. To indicate response completion return false. + if self._offsetRead < self._webRequestClient._dataLength: + dataChunk = self._webRequestClient._data[\ + self._offsetRead:(self._offsetRead + bytesToRead)] + self._offsetRead += len(dataChunk) + dataOut[0] = dataChunk + bytesReadOut[0] = len(dataChunk) + return True + self._clientHandler._ReleaseStrongReference(self) + print("no more data, return False") + return False + + def CanGetCookie(self, cookie): + # Return true if the specified cookie can be sent + # with the request or false otherwise. If false + # is returned for any cookie then no cookies will + # be sent with the request. + return True + + def CanSetCookie(self, cookie): + # Return true if the specified cookie returned + # with the response can be set or false otherwise. + return True + + def Cancel(self): + # Request processing has been canceled. + pass + +class WebRequestClient: + + _resourceHandler = None + _data = "" + _dataLength = -1 + _response = None + + def OnUploadProgress(self, webRequest, current, total): + pass + + def OnDownloadProgress(self, webRequest, current, total): + pass + + def OnDownloadData(self, webRequest, data): + # print("OnDownloadData()") + self._data += data + + def OnRequestComplete(self, webRequest): + print("OnRequestComplete()") + # cefpython.WebRequest.Status = {"Unknown", "Success", + # "Pending", "Canceled", "Failed"} + statusText = "Unknown" + if webRequest.GetRequestStatus() in cefpython.WebRequest.Status: + statusText = cefpython.WebRequest.Status[\ + webRequest.GetRequestStatus()] + print("status = %s" % statusText) + print("error code = %s" % webRequest.GetRequestError()) + # Emulate OnResourceResponse() in ClientHandler: + self._response = webRequest.GetResponse() + # Are webRequest.GetRequest() and + # self._resourceHandler._request the same? What if + # there was a redirect, what will GetUrl() return + # for both of them? + self._data = self._resourceHandler._clientHandler._OnResourceResponse( + self._resourceHandler._browser, + self._resourceHandler._frame, + webRequest.GetRequest(), + webRequest.GetRequestStatus(), + webRequest.GetRequestError(), + webRequest.GetResponse(), + self._data) + self._dataLength = len(self._data) + # ResourceHandler.GetResponseHeaders() will get called + # after _responseHeadersReadyCallback.Continue() is called. + self._resourceHandler._responseHeadersReadyCallback.Continue() + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(800,600)) + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.mainPanel.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings={"plugins_disabled": False, + "default_encoding": BROWSER_DEFAULT_ENCODING}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + clientHandler = ClientHandler() + self.browser.SetClientHandler(clientHandler) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # In wx.chromectrl calling browser.CloseBrowser() and/or + # self.Destroy() in OnClose is causing crashes when embedding + # multiple browser tabs. The solution is to call only + # browser.ParentWindowWillClose. Behavior of this example + # seems different as it extends wx.Frame, while ChromeWindow + # from chromectrl extends wx.Window. Calling CloseBrowser + # and Destroy does not cause crashes, but is not recommended. + # Call ParentWindowWillClose and event.Skip() instead. See + # also Issue 107. + self.browser.ParentWindowWillClose() + event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("wxpython.py: OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +if __name__ == '__main__': + sys.excepthook = ExceptHook + settings = { + "debug": False, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + } + # print("browser_subprocess_path="+settings["browser_subprocess_path"]) + cefpython.Initialize(settings) + print('wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_32bit/wxpython.html b/cefpython/cef3/linux/binaries_32bit/wxpython.html new file mode 100644 index 00000000..caf056ff --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/wxpython.html @@ -0,0 +1,707 @@ + + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + +Use the mouse context menu to go Back/Forward in history navigation. + +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
+ +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key which is handled in KeyboardHandler.OnKeyEvent
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python') +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)  
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ +Try this: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu to return back +here after visiting the url:
+ + https://tv.eurosport.com/do-not-allow +
+ +This url will be allowed:
+ + https://tv.eurosport.com/ + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
    + Or visit it in a js popup:
    + + javascript:window.open('http://www.html-kit.com/tools/cookietester/') +
  2. +
  3. Open cookietester in a popup:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie: +external.SetCookie() +
+ +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+ + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +Try this: + + http://www.non-existent.nono/ +

+ +Note: after you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/linux/binaries_32bit/wxpython.py b/cefpython/cef3/linux/binaries_32bit/wxpython.py new file mode 100644 index 00000000..2ad47bc9 --- /dev/null +++ b/cefpython/cef3/linux/binaries_32bit/wxpython.py @@ -0,0 +1,786 @@ +# An example of embedding CEF browser in wxPython on Linux. +# Tested with wxPython 2.8.12.1 (gtk2-unicode). +# To install wxPython type "sudo apt-get install python-wxtools". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import a local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect + +g_browserSettings = None + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def __init__(self, url=None): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(1024,768)) + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.mainPanel.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings=g_browserSettings, + navigateUrl=url) + + clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + jsBindings.SetObject("external", JavascriptExternal(self.browser)) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # In wx.chromectrl calling browser.CloseBrowser() and/or + # self.Destroy() in OnClose is causing crashes when embedding + # multiple browser tabs. The solution is to call only + # browser.ParentWindowWillClose. Behavior of this example + # seems different as it extends wx.Frame, while ChromeWindow + # from chromectrl extends wx.Window. Calling CloseBrowser + # and Destroy does not cause crashes, but is not recommended. + # Call ParentWindowWillClose and event.Skip() instead. See + # also Issue 107. + self.browser.ParentWindowWillClose() + event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def CreateAnotherBrowser(self, url=None): + """ + TODO: There are errors in the console when closing the window: + >> Check failed: window + >> Gdk: _gdk_window_destroy_hierarchy: assertion `GDK_IS_WINDOW\ + >> (window)' failed + >> GLib-GObject: g_object_unref: assertion `G_IS_OBJECT (object)' failed + """ + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.GetMainFrame().ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s"\ + % event["focus_on_editable_field"]) + if platform.system() == "Linux": + # F5 + if event["native_key_code"] == 71: + print("[wxpython.py] F5 pressed, calling"\ + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if event["native_key_code"] == 9: + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if event["native_key_code"] == 96: + print("[wxpython.py] F12 pressed, calling"\ + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + elif platform.system() == "Windows": + # F5 todo + # Escape todo + pass + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl.startswith( + "https://tv.eurosport.com/do-not-allow"): + print(" Not allowed!") + return False + if requestUrl.startswith( + "https://tv.eurosport.com/"): + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load"\ + " error: Esc was pressed or file download was aborted") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName,\ + popupFeatures, windowInfo, client, browserSettings,\ + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + allowPopups = True + return not allowPopups + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("[wxpython.py] OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + +if __name__ == '__main__': + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + # These directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + "downloads_enabled": True, + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": False, + } + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "remote-debugging-port": "12345", + # "disable-gpu": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_64bit/LICENSE.txt b/cefpython/cef3/linux/binaries_64bit/LICENSE.txt new file mode 100644 index 00000000..ba1b96ff --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright (c) 2012-2014 The CEF Python authors. All rights +reserved. Website: http://code.google.com/p/cefpython/ + +This product includes the following third party libraries: +* Chromium Embedded Framework licensed under the BSD 3-clause + license. Website: http://code.google.com/p/chromiumembedded/ + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef3/linux/binaries_64bit/README.txt b/cefpython/cef3/linux/binaries_64bit/README.txt new file mode 100644 index 00000000..7eafd151 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/README.txt @@ -0,0 +1,97 @@ +Chromium Embedded Framework (CEF) Standard Binary Distribution for Linux +------------------------------------------------------------------------------- + +Date: July 24, 2014 + +CEF Version: 3.1650.1639 +CEF URL: http://chromiumembedded.googlecode.com/svn/branches/1650/cef3@1639 + +Chromium Verison: 31.0.1650.69 +Chromium URL: http://src.chromium.org/svn/branches/1650/src@241641 + +This distribution contains all components necessary to build and distribute an +application using CEF on the Linux platform. Please see the LICENSING +section of this document for licensing terms and conditions. + + +CONTENTS +-------- + +cefclient Contains the cefclient sample application configured to build + using the files in this distribution. + +Debug Contains libcef.so and other components required to run the debug + version of CEF-based applications. By default these files should be + placed in the same directory as the executable and will be copied + there as part of the build process. + +include Contains all required CEF header files. + +libcef_dll Contains the source code for the libcef_dll_wrapper static library + that all applications using the CEF C++ API must link against. + +Release Contains libcef.so and other components required to run the release + version of CEF-based applications. By default these files should be + placed in the same directory as the executable and will be copied + there as part of the build process. + +Resources Contains resources required by libcef.so. By default these files + should be placed in the same directory as libcef.so and will be + copied there as part of the build process. + + +USAGE +----- + +Run 'build.sh Debug' to build the cefclient target in Debug mode. + +Please visit the CEF Website for additional usage information. + +http://code.google.com/p/chromiumembedded + + +REDISTRIBUTION +-------------- + +This binary distribution contains the below components. Components listed under +the "required" section must be redistributed with all applications using CEF. +Components listed under the "optional" section may be excluded if the related +features will not be used. + +Required components: + +* CEF core library + libcef.so + +Optional components: + +* Localized resources + locales/ + Note: Contains localized strings for WebKit UI controls. A .pak file is loaded + from this folder based on the value of environment variables which are read + with the following precedence order: LANGUAGE, LC_ALL, LC_MESSAGES and LANG. + Only configured locales need to be distributed. If no locale is configured the + default locale of "en-US" will be used. Locale file loading can be disabled + completely using CefSettings.pack_loading_disabled. The locales folder path + can be customized using CefSettings.locales_dir_path. + +* Other resources + cef.pak + devtools_resources.pak + Note: Contains WebKit image and inspector resources. Pack file loading can be + disabled completely using CefSettings.pack_loading_disabled. The resources + directory path can be customized using CefSettings.resources_dir_path. + +* FFmpeg audio and video support + libffmpegsumo.so + Note: Without this component HTML5 audio and video will not function. + + +LICENSING +--------- + +The CEF project is BSD licensed. Please read the LICENSE.txt file included with +this binary distribution for licensing terms and conditions. Other software +included in this distribution is provided under other licenses. Please visit +"about:credits" in a CEF-based application for complete Chromium and third-party +licensing information. diff --git a/cefpython/cef3/linux/binaries_64bit/example.html b/cefpython/cef3/linux/binaries_64bit/example.html new file mode 100644 index 00000000..891bc5e8 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/example.html @@ -0,0 +1,58 @@ + + + + + CEF Python 3 example (utf-8: ąś) + + + + + + +

Use mouse context menu to go Back/Forward in history navigation.

+ + + +

Google Search

+https://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('example.html') + + + +

HTML5 video and accelerated content

+ +HTML 5 video
+ +Accelerated canvas
+ +Accelerated layers
+ + + +

Advanced example

+ +See the wxpython.py script for an advanced usage of CEF Python 3 +features - including javascript bindings, js and python callbacks, +client handlers and others. + + +



+



+



+



+ + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/binding.html b/cefpython/cef3/linux/binaries_64bit/files/binding.html new file mode 100644 index 00000000..f32db392 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/binding.html @@ -0,0 +1,27 @@ + + +Binding Test + + + + +
+Message: +
+
You should see the reverse of your message below: +
+
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/files/dialogs.html b/cefpython/cef3/linux/binaries_64bit/files/dialogs.html new file mode 100644 index 00000000..b815a5e4 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/dialogs.html @@ -0,0 +1,64 @@ + + +Dialog Test + + + +
+Click a button to show the associated dialog type. +
+
+
+
input type="file": +
+
+
+

+
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/files/domaccess.html b/cefpython/cef3/linux/binaries_64bit/files/domaccess.html new file mode 100644 index 00000000..87bd23e3 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/domaccess.html @@ -0,0 +1,13 @@ + + +

Select some portion of the below page content and click the "Describe Selection" button. The selected region will then be described below.

+

This is p1

+

This is p2

+

This is p3

+

This is p4

+
+ +

The description will appear here.

+
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/files/localstorage.html b/cefpython/cef3/linux/binaries_64bit/files/localstorage.html new file mode 100644 index 00000000..87c6e68c --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/localstorage.html @@ -0,0 +1,24 @@ + + + +Click the "Add Line" button to add a line or the "Clear" button to clear.
+This data will persist across sessions if a cache path was specified.
+ + +
+ + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/logo.png b/cefpython/cef3/linux/binaries_64bit/files/logo.png new file mode 100644 index 00000000..41dd728d Binary files /dev/null and b/cefpython/cef3/linux/binaries_64bit/files/logo.png differ diff --git a/cefpython/cef3/linux/binaries_64bit/files/osr_test.html b/cefpython/cef3/linux/binaries_64bit/files/osr_test.html new file mode 100644 index 00000000..8e655a34 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/osr_test.html @@ -0,0 +1,69 @@ + + OSR Test + + + +

+ OSR Testing h1 - Focus and blur + + this page and will get this red black +

+
    +
  1. OnPaint should be called each time a page loads
  2. +
  3. Move mouse + to require an OnCursorChange call
  4. +
  5. Hover will color this with + red. Will trigger OnPaint once on enter and once on leave
  6. +
  7. Right clicking will show contextual menu and will request + GetScreenPoint
  8. +
  9. IsWindowRenderingDisabled should be true
  10. +
  11. WasResized should trigger full repaint if size changes. +
  12. +
  13. Invalidate should trigger OnPaint once
  14. +
  15. Click and write here with SendKeyEvent to trigger repaints: +
  16. +
  17. Click here with SendMouseClickEvent to navigate: +
  18. +
  19. Mouse over this element will + trigger show a tooltip
  20. +
+
+
+
+
+
+
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/files/other_tests.html b/cefpython/cef3/linux/binaries_64bit/files/other_tests.html new file mode 100644 index 00000000..a36ca453 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/other_tests.html @@ -0,0 +1,33 @@ + + +Other Tests + + +

Various other internal and external tests.

+ + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/performance.html b/cefpython/cef3/linux/binaries_64bit/files/performance.html new file mode 100644 index 00000000..aa64d51d --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/performance.html @@ -0,0 +1,293 @@ + + + + Performance Tests + + + +

Performance Tests

+ Filter: +
+ +
+ + + + + + + + + + + + + +
NameIterations per RunAvg (ms)Min (ms)Max (ms)StdDev (ms)Runs (ms)
+
+ +
+ + Result 1: +
Result 2: +
+ +
+ + + + + + + + + + +
NameResult 1 Avg (ms)Result 2 Avg (ms)% Diff
+
+ + + + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/performance2.html b/cefpython/cef3/linux/binaries_64bit/files/performance2.html new file mode 100644 index 00000000..6664de7b --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/performance2.html @@ -0,0 +1,442 @@ + + + + Performance Tests (2) + + + +

Performance Tests (2)

+ +
+ + + + + + + + + + + + + + + + + + + +
Settings:
Iterations:
Samples:
Mode:Asynchronous + Synchronous +
+
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + +
EnabledNameSamples x IterationsMin, msAvg, msMax, msAverage calls/secMeasuring InacurracyMemory, MBMemory delta, MBDescription
+
+ + + + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/transparency.html b/cefpython/cef3/linux/binaries_64bit/files/transparency.html new file mode 100644 index 00000000..a8dd3b46 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/transparency.html @@ -0,0 +1,63 @@ + + + +Transparency Examples + + + + +

Image Transparency

+Hover over an image to make it fully opaque.
+klematis +klematis + +

Block Transparency

+White 0% White 25% White 50% White 75% White 100% +
+Black 0% Black 25% Black 50% Black 75% Black 100% + + + diff --git a/cefpython/cef3/linux/binaries_64bit/files/window.html b/cefpython/cef3/linux/binaries_64bit/files/window.html new file mode 100644 index 00000000..4521ccb5 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/window.html @@ -0,0 +1,44 @@ + + +Window Test + + + +
+Click a button to perform the associated window action. +
+
+
(minimizes and then restores the window as topmost) +
X: Y: Width: Height: +
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/files/xmlhttprequest.html b/cefpython/cef3/linux/binaries_64bit/files/xmlhttprequest.html new file mode 100644 index 00000000..051f8148 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/files/xmlhttprequest.html @@ -0,0 +1,19 @@ + + + +
+URL: +
+
+
+ + diff --git a/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.css b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.css new file mode 100755 index 00000000..46ce5e40 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.css @@ -0,0 +1,186 @@ +/* + IMPORTANT: + 1. DO NOT USE DOUBLE QUOTES HERE! + This file contents is included on page using document.write: + | (DQ = double quote) + | document.write(DQDQ); + 2. Each attribute must end with a semicolon, as newlines are removed + from this file. +*/ + +/* Dropdown control */ +.__kivy__selectBox-dropdown { + min-width: 150px; + position: relative; + border: solid 1px #BBB; + line-height: 1.5; + text-decoration: none; + text-align: left; + color: #000; + outline: none; + vertical-align: middle; + background: #F2F2F2; + background: -moz-linear-gradient(top, #F8F8F8 1%, #E1E1E1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(1%, #F8F8F8), color-stop(100%, #E1E1E1)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F8F8F8', endColorstr='#E1E1E1', GradientType=0); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + box-shadow: 0 1px 0 rgba(255, 255, 255, .75); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + display: inline-block; + cursor: default; +} + +.__kivy__selectBox-dropdown:focus, +.__kivy__selectBox-dropdown:focus .__kivy__selectBox-arrow { + border-color: #666; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-menuShowing-bottom { + -moz-border-radius-bottomleft: 0; + -moz-border-radius-bottomright: 0; + -webkit-border-bottom-left-radius: 0; + -webkit-border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-menuShowing-top { + -moz-border-radius-topleft: 0; + -moz-border-radius-topright: 0; + -webkit-border-top-left-radius: 0; + -webkit-border-top-right-radius: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.__kivy__selectBox-dropdown .__kivy__selectBox-label { + padding: 2px 8px; + display: inline-block; + white-space: nowrap; + overflow: hidden; +} + +.__kivy__selectBox-dropdown .__kivy__selectBox-arrow { + position: absolute; + top: 0; + right: 0; + width: 23px; + height: 100%; + background: url(data:image/gif;base64,R0lGODlhCQAOAIABAAAAAP///yH5BAEAAAEALAAAAAAJAA4AAAIXjAOnwIrcDJxvQoez3tUmn0jUEjmhUQAAOw==) 50% center no-repeat; + border-left: solid 1px #BBB; +} + +/* Dropdown menu */ +.__kivy__selectBox-dropdown-menu { + position: absolute; + z-index: 99999; + max-height: 200px; + min-height: 1em; + border: solid 1px #BBB; /* should be the same border width as .__kivy__selectBox-dropdown */ + background: #FFF; + -moz-box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + box-shadow: 0 2px 6px rgba(0, 0, 0, .2); + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +/* Inline control */ +.__kivy__selectBox-inline { + min-width: 150px; + outline: none; + border: solid 1px #BBB; + background: #FFF; + display: inline-block; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + overflow: auto; +} + +.__kivy__selectBox-inline:focus { + border-color: #666; +} + +/* Options */ +.__kivy__selectBox-options, +.__kivy__selectBox-options LI, +.__kivy__selectBox-options LI A { + list-style: none; + display: block; + cursor: default; + padding: 0; + margin: 0; +} + +.__kivy__selectBox-options.__kivy__selectBox-options-top{ + border-bottom:none; + margin-top:1px; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; + -webkit-border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} +.__kivy__selectBox-options.__kivy__selectBox-options-bottom{ + border-top:none; + -moz-border-radius-bottomleft: 5px; + -moz-border-radius-bottomright: 5px; + -webkit-border-bottom-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +.__kivy__selectBox-options LI A { + line-height: 1.5; + padding: 0 .5em; + white-space: nowrap; + overflow: hidden; + background: 6px center no-repeat; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-hover A { + background-color: #EEE; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-disabled A { + color: #888; + background-color: transparent; +} + +.__kivy__selectBox-options LI.__kivy__selectBox-selected A { + background-color: #C8DEF4; +} + +.__kivy__selectBox-options .__kivy__selectBox-optgroup { + color: #666; + background: #EEE; + font-weight: bold; + line-height: 1.5; + padding: 0 .3em; + white-space: nowrap; +} + +/* Disabled state */ +.__kivy__selectBox.__kivy__selectBox-disabled { + color: #888 !important; +} + +.__kivy__selectBox-dropdown.__kivy__selectBox-disabled .__kivy__selectBox-arrow { + opacity: .5; + filter: alpha(opacity=50); + border-color: #666; +} + +.__kivy__selectBox-inline.__kivy__selectBox-disabled { + color: #888 !important; +} + +.__kivy__selectBox-inline.__kivy__selectBox-disabled .__kivy__selectBox-options A { + background-color: transparent !important; +} diff --git a/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.js b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.js new file mode 100755 index 00000000..a7d3d229 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/kivy-selectBox.js @@ -0,0 +1,10420 @@ +/*! + * __kivy__jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var __kivy__jQuery = (function() { + +// Define a local copy of __kivy__jQuery +var __kivy__jQuery = function( selector, context ) { + // The __kivy__jQuery object is actually just the init constructor 'enhanced' + return new __kivy__jQuery.fn.init( selector, context, root__kivy__jQuery ); + }, + + // Map over __kivy__jQuery in case of overwrite + ___kivy__jQuery = window.__kivy__jQuery, + + // Map over the $ in case of overwrite + __kivy___$ = window.__kivy__$, + + // A central reference to the root __kivy__jQuery(document) + root__kivy__jQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by __kivy__jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with __kivy__jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +__kivy__jQuery.fn = __kivy__jQuery.prototype = { + constructor: __kivy__jQuery, + init: function( selector, context, root__kivy__jQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof __kivy__jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( __kivy__jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + __kivy__jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = __kivy__jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? __kivy__jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return __kivy__jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return root__kivy__jQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the __kivy__jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.__kivy__jquery ) { + return ( context || root__kivy__jQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( __kivy__jQuery.isFunction( selector ) ) { + return root__kivy__jQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return __kivy__jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of __kivy__jQuery being used + __kivy__jquery: "1.7.1", + + // The default length of a __kivy__jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new __kivy__jQuery matched element set + var ret = this.constructor(); + + if ( __kivy__jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + __kivy__jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return __kivy__jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + __kivy__jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( __kivy__jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a __kivy__jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the __kivy__jQuery prototype for later instantiation +__kivy__jQuery.fn.init.prototype = __kivy__jQuery.fn; + +__kivy__jQuery.extend = __kivy__jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !__kivy__jQuery.isFunction(target) ) { + target = {}; + } + + // extend __kivy__jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( __kivy__jQuery.isPlainObject(copy) || (copyIsArray = __kivy__jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && __kivy__jQuery.isArray(src) ? src : []; + + } else { + clone = src && __kivy__jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = __kivy__jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +__kivy__jQuery.extend({ + noConflict: function( deep ) { + if ( window.__kivy__$ === __kivy__jQuery ) { + window.__kivy__$ = __kivy___$; + } + + if ( deep && window.__kivy__jQuery === __kivy__jQuery ) { + window.__kivy__jQuery = ___kivy__jQuery; + } + + return __kivy__jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + __kivy__jQuery.readyWait++; + } else { + __kivy__jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--__kivy__jQuery.readyWait) || (wait !== true && !__kivy__jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( __kivy__jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + __kivy__jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --__kivy__jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ __kivy__jQuery ] ); + + // Trigger any bound ready events + if ( __kivy__jQuery.fn.trigger ) { + __kivy__jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = __kivy__jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( __kivy__jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", __kivy__jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", __kivy__jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return __kivy__jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return __kivy__jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || __kivy__jQuery.type(obj) !== "object" || obj.nodeType || __kivy__jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = __kivy__jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + __kivy__jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + __kivy__jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than __kivy__jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || __kivy__jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = __kivy__jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || __kivy__jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + __kivy__jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof __kivy__jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || __kivy__jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !__kivy__jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || __kivy__jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + __kivy__jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && __kivy__jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of __kivy__jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/__kivy__jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function __kivy__jQuerySub( selector, context ) { + return new __kivy__jQuerySub.fn.init( selector, context ); + } + __kivy__jQuery.extend( true, __kivy__jQuerySub, this ); + __kivy__jQuerySub.superclass = this; + __kivy__jQuerySub.fn = __kivy__jQuerySub.prototype = this(); + __kivy__jQuerySub.fn.constructor = __kivy__jQuerySub; + __kivy__jQuerySub.sub = this.sub; + __kivy__jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof __kivy__jQuery && !(context instanceof __kivy__jQuerySub) ) { + context = __kivy__jQuerySub( context ); + } + + return __kivy__jQuery.fn.init.call( this, selector, context, root__kivy__jQuerySub ); + }; + __kivy__jQuerySub.fn.init.prototype = __kivy__jQuerySub.fn; + var root__kivy__jQuerySub = __kivy__jQuerySub(document); + return __kivy__jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +__kivy__jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = __kivy__jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + __kivy__jQuery.browser[ browserMatch.browser ] = true; + __kivy__jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use __kivy__jQuery.browser.webkit instead +if ( __kivy__jQuery.browser.webkit ) { + __kivy__jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All __kivy__jQuery objects should point back to these +root__kivy__jQuery = __kivy__jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + __kivy__jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + __kivy__jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( __kivy__jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + __kivy__jQuery.ready(); +} + +return __kivy__jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +__kivy__jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = __kivy__jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +__kivy__jQuery.extend({ + + Deferred: function( func ) { + var doneList = __kivy__jQuery.Callbacks( "once memory" ), + failList = __kivy__jQuery.Callbacks( "once memory" ), + progressList = __kivy__jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return __kivy__jQuery.Deferred(function( newDefer ) { + __kivy__jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( __kivy__jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && __kivy__jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && __kivy__jQuery.isFunction( firstParam.promise ) ? + firstParam : + __kivy__jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && __kivy__jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +__kivy__jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + __kivy__jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + __kivy__jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + __kivy__jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +__kivy__jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of __kivy__jQuery on the page + // Non-digits removed to match rinline__kivy__jQuery + expando: "__kivy__jQuery" + ( __kivy__jQuery.fn.__kivy__jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? __kivy__jQuery.cache[ elem[__kivy__jQuery.expando] ] : elem[ __kivy__jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !__kivy__jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = __kivy__jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global __kivy__jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? __kivy__jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++__kivy__jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing __kivy__jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = __kivy__jQuery.noop; + } + } + + // An object can be passed to __kivy__jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = __kivy__jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = __kivy__jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // __kivy__jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ __kivy__jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using __kivy__jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ __kivy__jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !__kivy__jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = __kivy__jQuery.expando, + + isNode = elem.nodeType, + + // See __kivy__jQuery.data for more information + cache = isNode ? __kivy__jQuery.cache : elem, + + // See __kivy__jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !__kivy__jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = __kivy__jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : __kivy__jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See __kivy__jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( __kivy__jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( __kivy__jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return __kivy__jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = __kivy__jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +__kivy__jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = __kivy__jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !__kivy__jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = __kivy__jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + __kivy__jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + __kivy__jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = __kivy__jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = __kivy__jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + __kivy__jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + __kivy__jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + __kivy__jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? __kivy__jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + __kivy__jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && __kivy__jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = __kivy__jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !__kivy__jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !__kivy__jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !__kivy__jQuery._data( elem, queueDataKey ) && + !__kivy__jQuery._data( elem, markDataKey ) ) { + __kivy__jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +__kivy__jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + __kivy__jQuery._data( elem, type, (__kivy__jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (__kivy__jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + __kivy__jQuery._data( elem, key, count ); + } else { + __kivy__jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = __kivy__jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || __kivy__jQuery.isArray(data) ) { + q = __kivy__jQuery._data( elem, type, __kivy__jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = __kivy__jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + __kivy__jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + __kivy__jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + __kivy__jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +__kivy__jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return __kivy__jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = __kivy__jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + __kivy__jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + __kivy__jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = __kivy__jQuery.fx ? __kivy__jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = __kivy__jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = __kivy__jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( __kivy__jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + __kivy__jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + __kivy__jQuery.data( elements[ i ], deferDataKey, __kivy__jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = __kivy__jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +__kivy__jQuery.fn.extend({ + attr: function( name, value ) { + return __kivy__jQuery.access( this, name, value, true, __kivy__jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + __kivy__jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return __kivy__jQuery.access( this, name, value, true, __kivy__jQuery.prop ); + }, + + removeProp: function( name ) { + name = __kivy__jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( j ) { + __kivy__jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = __kivy__jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( j ) { + __kivy__jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = __kivy__jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( __kivy__jQuery.isFunction( value ) ) { + return this.each(function( i ) { + __kivy__jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = __kivy__jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + __kivy__jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : __kivy__jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = __kivy__jQuery.valHooks[ elem.nodeName.toLowerCase() ] || __kivy__jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = __kivy__jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = __kivy__jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( __kivy__jQuery.isArray( val ) ) { + val = __kivy__jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = __kivy__jQuery.valHooks[ this.nodeName.toLowerCase() ] || __kivy__jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +__kivy__jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (__kivy__jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !__kivy__jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = __kivy__jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return __kivy__jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = __kivy__jQuery.makeArray( value ); + + __kivy__jQuery(elem).find("option").each(function() { + this.selected = __kivy__jQuery.inArray( __kivy__jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in __kivy__jQuery.attrFn ) { + return __kivy__jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return __kivy__jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !__kivy__jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = __kivy__jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + __kivy__jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = __kivy__jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + __kivy__jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + __kivy__jQuery.error( "type property can't be changed" ); + } else if ( !__kivy__jQuery.support.radioValue && value === "radio" && __kivy__jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && __kivy__jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && __kivy__jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !__kivy__jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = __kivy__jQuery.propFix[ name ] || name; + hooks = __kivy__jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +__kivy__jQuery.attrHooks.tabindex = __kivy__jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = __kivy__jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + __kivy__jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = __kivy__jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = __kivy__jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + __kivy__jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + __kivy__jQuery.each([ "width", "height" ], function( i, name ) { + __kivy__jQuery.attrHooks[ name ] = __kivy__jQuery.extend( __kivy__jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + __kivy__jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !__kivy__jQuery.support.hrefNormalized ) { + __kivy__jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + __kivy__jQuery.attrHooks[ name ] = __kivy__jQuery.extend( __kivy__jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !__kivy__jQuery.support.style ) { + __kivy__jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !__kivy__jQuery.support.optSelected ) { + __kivy__jQuery.propHooks.selected = __kivy__jQuery.extend( __kivy__jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !__kivy__jQuery.support.enctype ) { + __kivy__jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !__kivy__jQuery.support.checkOn ) { + __kivy__jQuery.each([ "radio", "checkbox" ], function() { + __kivy__jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +__kivy__jQuery.each([ "radio", "checkbox" ], function() { + __kivy__jQuery.valHooks[ this ] = __kivy__jQuery.extend( __kivy__jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( __kivy__jQuery.isArray( value ) ) { + return ( elem.checked = __kivy__jQuery.inArray( __kivy__jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return __kivy__jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +__kivy__jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = __kivy__jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = __kivy__jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a __kivy__jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof __kivy__jQuery !== "undefined" && (!e || __kivy__jQuery.event.triggered !== e.type) ? + __kivy__jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // __kivy__jQuery(...).bind("mouseover mouseout", fn); + types = __kivy__jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = __kivy__jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = __kivy__jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = __kivy__jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + __kivy__jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = __kivy__jQuery.hasData( elem ) && __kivy__jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = __kivy__jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + __kivy__jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = __kivy__jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + __kivy__jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( __kivy__jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + __kivy__jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + __kivy__jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || __kivy__jQuery.event.customEvent[ type ]) && !__kivy__jQuery.event.global[ type ] ) { + // No __kivy__jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // __kivy__jQuery.Event object + event[ __kivy__jQuery.expando ] ? event : + // Object literal + new __kivy__jQuery.Event( type, event ) : + // Just the event type (string) + new __kivy__jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = __kivy__jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + __kivy__jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? __kivy__jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = __kivy__jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !__kivy__jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( __kivy__jQuery._data( cur, "events" ) || {} )[ event.type ] && __kivy__jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a __kivy__jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && __kivy__jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && __kivy__jQuery.nodeName( elem, "a" )) && __kivy__jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !__kivy__jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + __kivy__jQuery.event.triggered = type; + elem[ type ](); + __kivy__jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable __kivy__jQuery.Event from the native event object + event = __kivy__jQuery.event.fix( event || window.event ); + + var handlers = ( (__kivy__jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed __kivy__jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single __kivy__jQuery object for reuse with .is() + jqcur = __kivy__jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (__kivy__jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ __kivy__jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = __kivy__jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = __kivy__jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: __kivy__jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( __kivy__jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = __kivy__jQuery.extend( + new __kivy__jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + __kivy__jQuery.event.trigger( e, null, elem ); + } else { + __kivy__jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +__kivy__jQuery.event.handle = __kivy__jQuery.event.dispatch; + +__kivy__jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +__kivy__jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof __kivy__jQuery.Event) ) { + return new __kivy__jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + __kivy__jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || __kivy__jQuery.now(); + + // Mark it as fixed + this[ __kivy__jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// __kivy__jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +__kivy__jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +__kivy__jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + __kivy__jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !__kivy__jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !__kivy__jQuery.support.submitBubbles ) { + + __kivy__jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( __kivy__jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + __kivy__jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = __kivy__jQuery.nodeName( elem, "input" ) || __kivy__jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + __kivy__jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + __kivy__jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( __kivy__jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + __kivy__jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !__kivy__jQuery.support.changeBubbles ) { + + __kivy__jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + __kivy__jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + __kivy__jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + __kivy__jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + __kivy__jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + __kivy__jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + __kivy__jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + __kivy__jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !__kivy__jQuery.support.focusinBubbles ) { + __kivy__jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + __kivy__jQuery.event.simulate( fix, event.target, __kivy__jQuery.event.fix( event ), true ); + }; + + __kivy__jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +__kivy__jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + __kivy__jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = __kivy__jQuery.guid++ ); + } + return this.each( function() { + __kivy__jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched __kivy__jQuery.Event + var handleObj = types.handleObj; + __kivy__jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + __kivy__jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + __kivy__jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + __kivy__jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + __kivy__jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return __kivy__jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || __kivy__jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( __kivy__jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + __kivy__jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +__kivy__jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + __kivy__jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( __kivy__jQuery.attrFn ) { + __kivy__jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + __kivy__jQuery.event.fixHooks[ name ] = __kivy__jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + __kivy__jQuery.event.fixHooks[ name ] = __kivy__jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = __kivy__jQuery.attr; +Sizzle.selectors.attrMap = {}; +__kivy__jQuery.find = Sizzle; +__kivy__jQuery.expr = Sizzle.selectors; +__kivy__jQuery.expr[":"] = __kivy__jQuery.expr.filters; +__kivy__jQuery.unique = Sizzle.uniqueSort; +__kivy__jQuery.text = Sizzle.getText; +__kivy__jQuery.isXMLDoc = Sizzle.isXML; +__kivy__jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = __kivy__jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +__kivy__jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return __kivy__jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( __kivy__jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + __kivy__jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = __kivy__jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( __kivy__jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + __kivy__jQuery( selector, this.context ).index( this[0] ) >= 0 : + __kivy__jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of __kivy__jQuery 1.7) + if ( __kivy__jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( __kivy__jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + __kivy__jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : __kivy__jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? __kivy__jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return __kivy__jQuery.inArray( this[0], __kivy__jQuery( elem ) ); + } + + // Locate the position of the desired element + return __kivy__jQuery.inArray( + // If it receives a __kivy__jQuery object, the first element is used + elem.__kivy__jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + __kivy__jQuery( selector, context ) : + __kivy__jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = __kivy__jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + __kivy__jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +__kivy__jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return __kivy__jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return __kivy__jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return __kivy__jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return __kivy__jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return __kivy__jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return __kivy__jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return __kivy__jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return __kivy__jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return __kivy__jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + __kivy__jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + __kivy__jQuery.fn[ name ] = function( until, selector ) { + var ret = __kivy__jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = __kivy__jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? __kivy__jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +__kivy__jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + __kivy__jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + __kivy__jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !__kivy__jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( __kivy__jQuery.isFunction( qualifier ) ) { + return __kivy__jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return __kivy__jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = __kivy__jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return __kivy__jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = __kivy__jQuery.filter( qualifier, filtered ); + } + } + + return __kivy__jQuery.grep(elements, function( elem, i ) { + return ( __kivy__jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinline__kivy__jQuery = / __kivy__jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + +Some <select> element from JIRA:
+(click submit to test the post data sent)

+ + +
+ + + + + +
+ +

With Fixed as "selected":

+ + + +

Add new <select> element dynamically on a page:
+ (select boxes are checked every second on a page,
+ you should see a normal select element transforming
+ into js select box a moment after you click the button)

+ + + + + +
+ +

+ + + +

Test interaction with other webpages that already use some other
+ javascript boxes library. +

+ +

These links need to be opened in the kivy_.py example:

+ + + +

Some libraries that are not well-designed will display
+ the select element twice, take a look at this for example:

+ + + http://adam.co/lab/jquery/customselect/ (open in kivy_.py example) + +

+Although, it will still be functional, just with a display glitch. +

+ +

The following code was added to the + SelectBox library to transform <select> element into + js box only if it's visible on a webpage:

+ +
+    // This should fix interaction with other js boxes libraries,
+    // so that the select element does not appear twice.
+    if (!$(select).is(":visible")) {
+        return;
+    }
+
+ +Also this code gives one second to other select box libraries
+to do their stuff, before we start ours: + +
+    __kivy__jQuery(document).ready(function() {
+    // Transform select elements only after a second,
+    // this will give time other select boxes libraries
+    // included on a webpage to their stuff first.
+    window.setInterval(function(){
+        __kivy__jQuery(document).ready(function() { 
+            __kivy__jQuery("select").__kivy__selectBox(); 
+        });
+    }, 1000);
+});
+
+ + + + \ No newline at end of file diff --git a/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/readme.md b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/readme.md new file mode 100755 index 00000000..ad45aa7f --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/kivy-select-boxes/readme.md @@ -0,0 +1,156 @@ +# jQuery selectBox: A styleable replacement for SELECT elements + +_Licensed under the MIT license: http://opensource.org/licenses/MIT_ + +## Features + +* Supports OPTGROUPS +* Supports standard dropdown controls +* Supports multi-select controls (i.e. multiple="multiple") +* Supports inline controls (i.e. size="5") +* Fully accessible via keyboard +* Shift + click (or shift + enter) to select a range of options in multi-select controls +* Type to search when the control has focus +* Auto-height based on the size attribute (to use, omit the height property in your CSS!) +* Tested in IE7-IE9, Firefox 3-4, recent WebKit browsers, and Opera + + +## Usage + +Link to the JS file: + +```html + +``` + +Add the CSS file (or append contents to your own stylesheet): + +```html + +``` + +To initialize: + +```javascript +// default +$('select').selectBox(); + +// or with custom settings +$('select').selectBox({ + mobile: true, + menuSpeed: 'fast' +}); +``` + +## Settings + +| Key | Default | Values | Description | +| ---------------|:-------------:|---------------------------:|-------------------------------------------------:| +| mobile | `false` | Boolean | Disables the widget for mobile devices | +| menuTransition | `default` | `default`, `slide`, `fade` | The show/hide transition for dropdown menus | +| menuSpeed | `normal` | `slow`, `normal`, `fast` | The show/hide transition speed | +| loopOptions | `false` | Boolean | Flag to allow arrow keys to loop through options | + + +To specify settings after the init, use this syntax: + +```javascript +$('select').selectBox('settings', {settingName: value, ... }); +``` + +## Methods + +To call a method use this syntax: + +```javascript +$('select').selectBox('methodName', [option]); +``` + +### Available methods + + +| Key | Description | +| ---------------|-----------------------------------------------------------------------------------------------| +| create | Creates the control (default) | +| destroy | Destroys the selectBox control and reverts back to the original form control | +| disable | Disables the control (i.e. disabled="disabled") | +| enable | Enables the control | +| value | If passed with a value, sets the control to that value; otherwise returns the current value | +| options | If passed either a string of HTML or a JSON object, replaces the existing options; otherwise Returns the options container element as a jQuery object | +| control | Returns the selectBox control element (an anchor tag) for working with directly | +| refresh | Updates the selectBox control's options based on the original controls options | +| instance | Returns the SelectBox instance, where you have more methods available (only in v1.2.0-dev | + | available) as in the `SelectBox` class below. | + +## API `SelectBox` + +You can instantiate the selectBox also through a classic OOP way: + +```javascript +var selectBox = new SelectBox($('#mySelectBox'), settings = {}); +selectBox.showMenu(); +``` + +The public methods are: + +```javascript +refresh() +destroy() +disable() +enable() + +getLabelClass() +getLabelText() +getSelectElement() +getOptions(String type = 'inline'|'dropdown') + +hideMenus() +showMenu() + +setLabel() +setOptions(Object options) +setValue(String value) + +removeHover(HTMLElement li) +addHover(HTMLElement li) + +disableSelection(HTMLElement selector) +generateOptions(jQuery self, jQuery options) +handleKeyDown(event) +handleKeyPress(event) +init(options) +keepOptionInView(jQuery li, Boolean center) +refresh() +removeHover(HTMLElement li) +selectOption(HTMLElement li, event) +``` + +## Events + +Events are fired on the original select element. You can bind events like this: + +```javascript +$('select').selectBox().change(function () { + alert($(this).val()); +}); +``` + +### Available events + +| Key | Description | +| ---------------|-----------------------------------------------------------------------------------------------| +| focus | Fired when the control gains focus | +| blur | Fired when the control loses focus | +| change | Fired when the value of a control changes | +| beforeopen | Fired before a dropdown menu opens (cancelable) | +| open | Fired after a dropdown menu opens (not cancelable) | +| beforeclose | Fired before a dropdown menu closes (cancelable) | +| close | Fired after a dropdown menu closes (not cancelable) | + +### Known Issues + +* The blur and focus callbacks are not very reliable in IE7. The change callback works fine. + +## Credits + +Original plugin by Cory LaViska of A Beautiful Site, LLC. (http://www.abeautifulsite.net/) \ No newline at end of file diff --git a/cefpython/cef3/linux/binaries_64bit/kivy_.py b/cefpython/cef3/linux/binaries_64bit/kivy_.py new file mode 100644 index 00000000..e366e557 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/kivy_.py @@ -0,0 +1,678 @@ +# An example of embedding CEF browser in the Kivy framework. +# The browser is embedded using off-screen rendering mode. + +# Tested using Kivy 1.7.2 stable on Ubuntu 12.04 64-bit. + +# In this example kivy-lang is used to declare the layout which +# contains two buttons (back, forward) and the browser view. + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname( + os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +from kivy.app import App +from kivy.uix.widget import Widget +from kivy.graphics import Color, Rectangle, GraphicException +from kivy.clock import Clock +from kivy.graphics.texture import Texture +from kivy.core.window import Window +from kivy.lang import Builder +from kivy.uix.boxlayout import BoxLayout +from kivy.base import EventLoop + +####Kivy APP #### +Builder.load_string(""" + +: + orientation: 'vertical' + BoxLayout: + size_hint_y: None + width: 80 + Button: + text: "Back" + on_press: browser.go_back() + Button: + text: "Forward" + on_press: browser.go_forward() + CefBrowser: + id: browser + +""") + + + +class BrowserLayout(BoxLayout): + + def __init__(self, **kwargs): + super(BrowserLayout, self).__init__(**kwargs) + + + +class CefBrowser(Widget): + + # Keyboard mode: "global" or "local". + # 1. Global mode forwards keys to CEF all the time. + # 2. Local mode forwards keys to CEF only when an editable + # control is focused (input type=text|password or textarea). + keyboard_mode = "global" + + '''Represent a browser widget for kivy, which can be used like a normal widget. + ''' + def __init__(self, start_url='http://www.google.com/', **kwargs): + super(CefBrowser, self).__init__(**kwargs) + + self.start_url = start_url + + #Workaround for flexible size: + #start browser when the height has changed (done by layout) + #This has to be done like this because I wasn't able to change + #the texture size + #until runtime without core-dump. + self.bind(size = self.size_changed) + + + starting = True + def size_changed(self, *kwargs): + '''When the height of the cefbrowser widget got changed, create the browser + ''' + if self.starting: + if self.height != 100: + self.start_cef() + self.starting = False + else: + self.texture = Texture.create( + size=self.size, colorfmt='rgba', bufferfmt='ubyte') + self.texture.flip_vertical() + with self.canvas: + Color(1, 1, 1) + # This will cause segmentation fault: + # | self.rect = Rectangle(size=self.size, texture=self.texture) + # Update only the size: + self.rect.size = self.size + self.browser.WasResized() + + + def _cef_mes(self, *kwargs): + '''Get called every frame. + ''' + cefpython.MessageLoopWork() + + + def _update_rect(self, *kwargs): + '''Get called whenever the texture got updated. + => we need to reset the texture for the rectangle + ''' + self.rect.texture = self.texture + + + def start_cef(self): + '''Starts CEF. + ''' + # create texture & add it to canvas + self.texture = Texture.create( + size=self.size, colorfmt='rgba', bufferfmt='ubyte') + self.texture.flip_vertical() + with self.canvas: + Color(1, 1, 1) + self.rect = Rectangle(size=self.size, texture=self.texture) + + #configure cef + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, + "log_file": "debug.log", + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % (cefpython.GetModuleDirectory(), "subprocess")} + + #start idle + Clock.schedule_interval(self._cef_mes, 0) + + #init CEF + cefpython.Initialize(settings) + + #WindowInfo offscreen flag + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsOffscreen(0) + + #Create Broswer and naviagte to empty page <= OnPaint won't get called yet + browserSettings = {} + # The render handler callbacks are not yet set, thus an + # error report will be thrown in the console (when release + # DCHECKS are enabled), however don't worry, it is harmless. + # This is happening because calling GetViewRect will return + # false. That's why it is initially navigating to "about:blank". + # Later, a real url will be loaded using the LoadUrl() method + # and the GetViewRect will be called again. This time the render + # handler callbacks will be available, it will work fine from + # this point. + # -- + # Do not use "about:blank" as navigateUrl - this will cause + # the GoBack() and GoForward() methods to not work. + self.browser = cefpython.CreateBrowserSync(windowInfo, browserSettings, + navigateUrl=self.start_url) + + #set focus + self.browser.SendFocusEvent(True) + + self._client_handler = ClientHandler(self) + self.browser.SetClientHandler(self._client_handler) + self.set_js_bindings() + + #Call WasResized() => force cef to call GetViewRect() and OnPaint afterwards + self.browser.WasResized() + + # The browserWidget instance is required in OnLoadingStateChange(). + self.browser.SetUserData("browserWidget", self) + + if self.keyboard_mode == "global": + self.request_keyboard() + + # Clock.schedule_once(self.change_url, 5) + + + _client_handler = None + _js_bindings = None + + def set_js_bindings(self): + if not self._js_bindings: + self._js_bindings = cefpython.JavascriptBindings( + bindToFrames=True, bindToPopups=True) + self._js_bindings.SetFunction("__kivy__request_keyboard", + self.request_keyboard) + self._js_bindings.SetFunction("__kivy__release_keyboard", + self.release_keyboard) + self.browser.SetJavascriptBindings(self._js_bindings) + + + def change_url(self, *kwargs): + # Doing a javascript redirect instead of Navigate() + # solves the js bindings error. The url here need to + # be preceded with "http://". Calling StopLoad() + # might be a good idea before making the js navigation. + + self.browser.StopLoad() + self.browser.GetMainFrame().ExecuteJavascript( + "window.location='http://www.youtube.com/'") + + # Do not use Navigate() or GetMainFrame()->LoadURL(), + # as it causes the js bindings to be removed. There is + # a bug in CEF, that happens after a call to Navigate(). + # The OnBrowserDestroyed() callback is fired and causes + # the js bindings to be removed. See this topic for more + # details: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=11009 + + # OFF: + # | self.browser.Navigate("http://www.youtube.com/") + + _keyboard = None + + def request_keyboard(self): + print("request_keyboard()") + self._keyboard = EventLoop.window.request_keyboard( + self.release_keyboard, self) + self._keyboard.bind(on_key_down=self.on_key_down) + self._keyboard.bind(on_key_up=self.on_key_up) + self.is_shift1 = False + self.is_shift2 = False + self.is_ctrl1 = False + self.is_ctrl2 = False + self.is_alt1 = False + self.is_alt2 = False + # Not sure if it is still required to send the focus + # (some earlier bug), but it shouldn't hurt to call it. + self.browser.SendFocusEvent(True) + + + def release_keyboard(self): + # When using local keyboard mode, do all the request + # and releases of the keyboard through js bindings, + # otherwise some focus problems arise. + self.is_shift1 = False + self.is_shift2 = False + self.is_ctrl1 = False + self.is_ctrl2 = False + self.is_alt1 = False + self.is_alt2 = False + if not self._keyboard: + return + print("release_keyboard()") + self._keyboard.unbind(on_key_down=self.on_key_down) + self._keyboard.unbind(on_key_up=self.on_key_up) + self._keyboard.release() + + # Kivy does not provide modifiers in on_key_up, but these + # must be sent to CEF as well. + is_shift1 = False + is_shift2 = False + is_ctrl1 = False + is_ctrl2 = False + is_alt1 = False + is_alt2 = False + + def on_key_down(self, keyboard, keycode, text, modifiers): + # Notes: + # - right alt modifier is not sent by Kivy through modifiers param. + # print("on_key_down(): keycode = %s, text = %s, modifiers = %s" % ( + # keycode, text, modifiers)) + if keycode[0] == 27: + # On escape release the keyboard, see the injected + # javascript in OnLoadStart(). + self.browser.GetFocusedFrame().ExecuteJavascript( + "__kivy__on_escape()") + return + cefModifiers = cefpython.EVENTFLAG_NONE + if "shift" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_SHIFT_DOWN + if "ctrl" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_CONTROL_DOWN + if "alt" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_ALT_DOWN + if "capslock" in modifiers: + cefModifiers |= cefpython.EVENTFLAG_CAPS_LOCK_ON + # print("on_key_down(): cefModifiers = %s" % cefModifiers) + cef_keycode = self.translate_to_cef_keycode(keycode[0]) + keyEvent = { + "type": cefpython.KEYEVENT_RAWKEYDOWN, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("keydown keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + if keycode[0] == 304: + self.is_shift1 = True + elif keycode[0] == 303: + self.is_shift2 = True + elif keycode[0] == 306: + self.is_ctrl1 = True + elif keycode[0] == 305: + self.is_ctrl2 = True + elif keycode[0] == 308: + self.is_alt1 = True + elif keycode[0] == 313: + self.is_alt2 = True + + + def on_key_up(self, keyboard, keycode): + # print("on_key_up(): keycode = %s" % (keycode,)) + cefModifiers = cefpython.EVENTFLAG_NONE + if self.is_shift1 or self.is_shift2: + cefModifiers |= cefpython.EVENTFLAG_SHIFT_DOWN + if self.is_ctrl1 or self.is_ctrl2: + cefModifiers |= cefpython.EVENTFLAG_CONTROL_DOWN + if self.is_alt1: + cefModifiers |= cefpython.EVENTFLAG_ALT_DOWN + # Capslock todo. + cef_keycode = self.translate_to_cef_keycode(keycode[0]) + keyEvent = { + "type": cefpython.KEYEVENT_KEYUP, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("keyup keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + keyEvent = { + "type": cefpython.KEYEVENT_CHAR, + "native_key_code": cef_keycode, + "modifiers": cefModifiers + } + # print("char keyEvent: %s" % keyEvent) + self.browser.SendKeyEvent(keyEvent) + if keycode[0] == 304: + self.is_shift1 = False + elif keycode[0] == 303: + self.is_shift2 = False + elif keycode[0] == 306: + self.is_ctrl1 = False + elif keycode[0] == 305: + self.is_ctrl2 = False + elif keycode[0] == 308: + self.is_alt1 = False + elif keycode[0] == 313: + self.is_alt2 = False + + + def translate_to_cef_keycode(self, keycode): + # TODO: this works on Linux, but on Windows the key + # mappings will probably be different. + # TODO: what if the Kivy keyboard layout is changed + # from qwerty to azerty? (F1 > options..) + cef_keycode = keycode + if self.is_alt2: + # The key mappings here for right alt were tested + # with the utf-8 charset on a webpage. If the charset + # is different there is a chance they won't work correctly. + alt2_map = { + # tilde + "96":172, + # 0-9 (48..57) + "48":125, "49":185, "50":178, "51":179, "52":188, + "53":189, "54":190, "55":123, "56":91, "57":93, + # minus + "45":92, + # a-z (97..122) + "97":433, "98":2771, "99":486, "100":240, "101":490, + "102":496, "103":959, "104":689, "105":2301, "106":65121, + "107":930, "108":435, "109":181, "110":497, "111":243, + "112":254, "113":64, "114":182, "115":438, "116":956, + "117":2302, "118":2770, "119":435, "120":444, "121":2299, + "122":447, + } + if str(keycode) in alt2_map: + cef_keycode = alt2_map[str(keycode)] + else: + print("Kivy to CEF key mapping not found (right alt), " \ + "key code = %s" % keycode) + shift_alt2_map = { + # tilde + "96":172, + # 0-9 (48..57) + "48":176, "49":161, "50":2755, "51":163, "52":36, + "53":2756, "54":2757, "55":2758, "56":2761, "57":177, + # minus + "45":191, + # A-Z (97..122) + "97":417, "98":2769, "99":454, "100":208, "101":458, + "102":170, "103":957, "104":673, "105":697, "106":65122, + "107":38, "108":419, "109":186, "110":465, "111":211, + "112":222, "113":2009, "114":174, "115":422, "116":940, + "117":2300, "118":2768, "119":419, "120":428, "121":165, + "122":431, + # special: <>? :" {} + "44":215, "46":247, "47":65110, + "59":65113, "39":65114, + "91":65112, "93":65108, + } + if self.is_shift1 or self.is_shift2: + if str(keycode) in shift_alt2_map: + cef_keycode = shift_alt2_map[str(keycode)] + else: + print("Kivy to CEF key mapping not found " \ + "(shift + right alt), key code = %s" % keycode) + elif self.is_shift1 or self.is_shift2: + shift_map = { + # tilde + "96":126, + # 0-9 (48..57) + "48":41, "49":33, "50":64, "51":35, "52":36, "53":37, + "54":94, "55":38, "56":42, "57":40, + # minus, plus + "45":95, "61":43, + # a-z (97..122) + "97":65, "98":66, "99":67, "100":68, "101":69, "102":70, + "103":71, "104":72, "105":73, "106":74, "107":75, "108":76, + "109":77, "110":78, "111":79, "112":80, "113":81, "114":82, + "115":83, "116":84, "117":85, "118":86, "119":87, "120":88, + "121":89, "122":90, + # special: <>? :" {} + "44":60, "46":62, "47":63, + "59":58, "39":34, + "91":123, "93":125, + } + if str(keycode) in shift_map: + cef_keycode = shift_map[str(keycode)] + # Other keys: + other_keys_map = { + # Escape + "27":65307, + # F1-F12 + "282":65470, "283":65471, "284":65472, "285":65473, + "286":65474, "287":65475, "288":65476, "289":65477, + "290":65478, "291":65479, "292":65480, "293":65481, + # Tab + "9":65289, + # Left Shift, Right Shift + "304":65505, "303":65506, + # Left Ctrl, Right Ctrl + "306":65507, "305": 65508, + # Left Alt, Right Alt + "308":65513, "313":65027, + # Backspace + "8":65288, + # Enter + "13":65293, + # PrScr, ScrLck, Pause + "316":65377, "302":65300, "19":65299, + # Insert, Delete, + # Home, End, + # Pgup, Pgdn + "277":65379, "127":65535, + "278":65360, "279":65367, + "280":65365, "281":65366, + # Arrows (left, up, right, down) + "276":65361, "273":65362, "275":65363, "274":65364, + } + if str(keycode) in other_keys_map: + cef_keycode = other_keys_map[str(keycode)] + return cef_keycode + + + def go_forward(self): + '''Going to forward in browser history + ''' + print "go forward" + self.browser.GoForward() + + + def go_back(self): + '''Going back in browser history + ''' + print "go back" + self.browser.GoBack() + + + def on_touch_down(self, touch, *kwargs): + if not self.collide_point(*touch.pos): + return + touch.grab(self) + + y = self.height-touch.pos[1] + self.browser.SendMouseClickEvent(touch.x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=False, clickCount=1) + + + def on_touch_move(self, touch, *kwargs): + if touch.grab_current is not self: + return + + y = self.height-touch.pos[1] + self.browser.SendMouseMoveEvent(touch.x, y, mouseLeave=False) + + + def on_touch_up(self, touch, *kwargs): + if touch.grab_current is not self: + return + + y = self.height-touch.pos[1] + self.browser.SendMouseClickEvent(touch.x, y, cefpython.MOUSEBUTTON_LEFT, + mouseUp=True, clickCount=1) + touch.ungrab(self) + + +class ClientHandler: + + def __init__(self, browserWidget): + self.browserWidget = browserWidget + + + def _fix_select_boxes(self, frame): + # This is just a temporary fix, until proper Popup widgets + # painting is implemented (PET_POPUP in OnPaint). Currently + # there is no way to obtain a native window handle (GtkWindow + # pointer) in Kivy, and this may cause things like context menus, + # select boxes and plugins not to display correctly. Although, + # this needs to be tested. The popup widget buffers are + # available in a separate paint buffer, so they could positioned + # freely so that it doesn't go out of the window. So the native + # window handle might not necessarily be required to make it work + # in most cases (99.9%). Though, this still needs testing to confirm. + # -- + # See this topic on the CEF Forum regarding the NULL window handle: + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10851 + # -- + # See also a related topic on the Kivy-users group: + # https://groups.google.com/d/topic/kivy-users/WdEQyHI5vTs/discussion + # -- + # The javascript select boxes library used: + # http://marcj.github.io/jquery-selectBox/ + # -- + # Cannot use "file://" urls to load local resources, error: + # | Not allowed to load local resource + print("_fix_select_boxes()") + resources_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "kivy-select-boxes") + if not os.path.exists(resources_dir): + print("The kivy-select-boxes directory does not exist, " \ + "select boxes fix won't be applied.") + return + js_file = os.path.join(resources_dir, "kivy-selectBox.js") + js_content = "" + with open(js_file, "r") as myfile: + js_content = myfile.read() + css_file = os.path.join(resources_dir, "kivy-selectBox.css") + css_content = "" + with open(css_file, "r") as myfile: + css_content = myfile.read() + css_content = css_content.replace("\r", "") + css_content = css_content.replace("\n", "") + jsCode = """ + %(js_content)s + var __kivy_temp_head = document.getElementsByTagName('head')[0]; + var __kivy_temp_style = document.createElement('style'); + __kivy_temp_style.type = 'text/css'; + __kivy_temp_style.appendChild(document.createTextNode("%(css_content)s")); + __kivy_temp_head.appendChild(__kivy_temp_style); + """ % locals() + frame.ExecuteJavascript(jsCode, + "kivy_.py > ClientHandler > OnLoadStart > _fix_select_boxes()") + + + def OnLoadStart(self, browser, frame): + self._fix_select_boxes(frame); + browserWidget = browser.GetUserData("browserWidget") + if browserWidget and browserWidget.keyboard_mode == "local": + print("OnLoadStart(): injecting focus listeners for text controls") + # The logic is similar to the one found in kivy-berkelium: + # https://github.com/kivy/kivy-berkelium/blob/master/berkelium/__init__.py + jsCode = """ + var __kivy__keyboard_requested = false; + function __kivy__keyboard_interval() { + var element = document.activeElement; + if (!element) { + return; + } + var tag = element.tagName; + var type = element.type; + if (tag == "INPUT" && (type == "" || type == "text" + || type == "password") || tag == "TEXTAREA") { + if (!__kivy__keyboard_requested) { + __kivy__request_keyboard(); + __kivy__keyboard_requested = true; + } + return; + } + if (__kivy__keyboard_requested) { + __kivy__release_keyboard(); + __kivy__keyboard_requested = false; + } + } + function __kivy__on_escape() { + if (document.activeElement) { + document.activeElement.blur(); + } + if (__kivy__keyboard_requested) { + __kivy__release_keyboard(); + __kivy__keyboard_requested = false; + } + } + setInterval(__kivy__keyboard_interval, 100); + """ + frame.ExecuteJavascript(jsCode, + "kivy_.py > ClientHandler > OnLoadStart") + + + def OnLoadEnd(self, browser, frame, httpStatusCode): + # Browser lost its focus after the LoadURL() and the + # OnBrowserDestroyed() callback bug. When keyboard mode + # is local the fix is in the request_keyboard() method. + # Call it from OnLoadEnd only when keyboard mode is global. + browserWidget = browser.GetUserData("browserWidget") + if browserWidget and browserWidget.keyboard_mode == "global": + browser.SendFocusEvent(True) + + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("OnLoadingStateChange(): isLoading = %s" % isLoading) + browserWidget = browser.GetUserData("browserWidget") + + + def OnPaint(self, browser, paintElementType, dirtyRects, buffer, width, + height): + # print "OnPaint()" + if paintElementType != cefpython.PET_VIEW: + print "Popups aren't implemented yet" + return + + #update buffer + buffer = buffer.GetString(mode="bgra", origin="top-left") + + #update texture of canvas rectangle + self.browserWidget.texture.blit_buffer(buffer, colorfmt='bgra', + bufferfmt='ubyte') + self.browserWidget._update_rect() + + return True + + + def GetViewRect(self, browser, rect): + width, height = self.browserWidget.texture.size + rect.append(0) + rect.append(0) + rect.append(width) + rect.append(height) + # print("GetViewRect(): %s x %s" % (width, height)) + return True + + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + suppressMessage[0] = True + return False + + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + callback.Continue(allow=True, userInput="") + return True + + +if __name__ == '__main__': + class CefBrowserApp(App): + def build(self): + return BrowserLayout() + CefBrowserApp().run() + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_64bit/prism.css b/cefpython/cef3/linux/binaries_64bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/linux/binaries_64bit/prism.js b/cefpython/cef3/linux/binaries_64bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/linux/binaries_64bit/pygtk_.py b/cefpython/cef3/linux/binaries_64bit/pygtk_.py new file mode 100644 index 00000000..e3afae4f --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/pygtk_.py @@ -0,0 +1,200 @@ +# An example of embedding the CEF browser in PyGTK on Linux. +# Tested with GTK "2.24.10". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import re + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pygtk_.py]: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + vbox = None + + def __init__(self): + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=800, height=600) + self.mainWindow.set_title('PyGTK CEF example') + self.mainWindow.realize() + + self.vbox = gtk.VBox(False, 0) + self.vbox.pack_start(self.CreateMenu(), False, False, 0) + self.mainWindow.add(self.vbox) + + m = re.search("GtkVBox at 0x(\w+)", str(self.vbox)) + hexID = m.group(1) + windowID = int(hexID, 16) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + browserSettings={}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + self.vbox.show() + self.mainWindow.show() + gobject.timeout_add(10, self.OnTimer) + + def CreateMenu(self): + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + + about = gtk.MenuItem('About') + about.show() + aboutmenu = gtk.Menu() + item = gtk.MenuItem('CEF Python') + aboutmenu.append(item) + item.show() + about.set_submenu(aboutmenu) + + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + + return menubar + + def OnWidgetClick(self, widget, data): + self.mainWindow.get_window().focus() + + def OnTimer(self): + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + # This function is currently not called by any of code, + # but if you would like for browser to have automatic focus + # add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + self.browser.SetFocus(True) + + def OnExit(self, widget, data=None): + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + version = '.'.join(map(str, list(gtk.gtk_version))) + print('[pygtk_.py] GTK version: %s' % version) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable + "release_dcheck_enabled": True, # Enable only when debugging + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + cefpython.Initialize(settings) + + gobject.threads_init() # Timer for the message loop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_64bit/pyqt.py b/cefpython/cef3/linux/binaries_64bit/pyqt.py new file mode 100644 index 00000000..2296b006 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/pyqt.py @@ -0,0 +1,239 @@ +# An example of embedding CEF browser in a PyQt4 application. +# Tested with PyQt "4.9.1". +# Command for installing PyQt4: "sudo apt-get install python-qt4". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +from PyQt4 import QtGui +from PyQt4 import QtCore + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pyqt.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PyQT CEF 3 example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + # cefpython.WindowUtils.OnSetFocus( + # int(self.centralWidget().winId()), 0, 0, 0) + pass + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QX11EmbedContainer): + browser = None + plug = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + + # QX11EmbedContainer provides an X11 window. The CEF + # browser can be embedded only by providing a GtkWidget + # pointer. So we're embedding a GtkPlug inside the X11 + # window. In latest CEF trunk it is possible to embed + # the CEF browser by providing X11 window id. So it will + # be possible to remove the GTK dependency from CEF + # Python in the future. + gtkPlugPtr = cefpython.WindowUtils.gtk_plug_new(\ + int(self.winId())) + print("[pyqt.py] MainFrame: GDK Native Window id: "+str(self.winId())) + print("[pyqt.py] MainFrame: GTK Plug ptr: "+str(gtkPlugPtr)) + + """ + Embedding GtkPlug is also possible with the pygtk module. + --------------------------------------------------------- + self.plug = gtk.Plug(self.winId()) + import re + m = re.search("GtkPlug at 0x(\w+)", str(self.plug)) + hexId = m.group(1) + gtkPlugPtr = int(hexId, 16) + ... + plug.show() + self.show() + --------------------------------------------------------- + """ + + windowInfo = cefpython.WindowInfo() + # Need to pass to CEF the GtkWidget* pointer + windowInfo.SetAsChild(gtkPlugPtr) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + cefpython.WindowUtils.gtk_widget_show(gtkPlugPtr) + self.show() + + def moveEvent(self, event): + # cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + pass + + def resizeEvent(self, event): + # cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + pass + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() + # returns False. + # But there is a bug in Qt, hasPendingEvents() returns + # always true. + # (The behavior described above was tested on Windows + # with pyqt 4.8, maybe this is not true anymore, + # test it TODO) + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to + # MessageLoopWork() should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("[pyqt.py] PyQt version: %s" % QtCore.PYQT_VERSION_STR) + print("[pyqt.py] QtCore version: %s" % QtCore.qVersion()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "enable-media-stream": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_64bit/wxpython-response.py b/cefpython/cef3/linux/binaries_64bit/wxpython-response.py new file mode 100644 index 00000000..9af202fd --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/wxpython-response.py @@ -0,0 +1,453 @@ +# An example of embedding CEF browser in wxPython on Linux. +# Tested with wxPython 2.8.12.1 (gtk2-unicode). +# To install wxPython type "sudo apt-get install python-wxtools". + +# This example implements a custom "_OnResourceResponse" callback +# that emulates reading response by utilizing Resourcehandler +# and WebRequest. + +FIX_ENCODING_BUG = True +BROWSER_DEFAULT_ENCODING = "utf-8" + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so') +if os.path.exists(libcef_so): + # Import local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import from package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import shutil + +class ClientHandler: + + # RequestHandler.GetResourceHandler() + def GetResourceHandler(self, browser, frame, request): + # Called on the IO thread before a resource is loaded. + # To allow the resource to load normally return None. + print("GetResourceHandler(): url = %s" % request.GetUrl()) + resHandler = ResourceHandler() + resHandler._clientHandler = self + resHandler._browser = browser + resHandler._frame = frame + resHandler._request = request + self._AddStrongReference(resHandler) + return resHandler + + def _OnResourceResponse(self, browser, frame, request, requestStatus, + requestError, response, data): + # This callback is emulated through ResourceHandler + # and WebRequest. Real "OnResourceResponse" is not yet + # available in CEF 3 (as of CEF revision 1450). See + # issue 515 in the CEF Issue Tracker: + # https://code.google.com/p/chromiumembedded/issues/detail?id=515 + # ---- + # requestStatus => cefpython.WebRequest.Status + # {"Unknown", "Success", "Pending", "Canceled", "Failed"} + # For "file://" requests the status will be "Unknown". + # requestError => see the NetworkError wiki page + # response.GetStatus() => http status code + print("_OnResourceResponse()") + print("data length = %s" % len(data)) + # Return the new data - you can modify it. + if request.GetUrl().startswith("file://") \ + and request.GetUrl().endswith("example.html"): + data = "This text was inserted through " \ + + "_OnResourceResponse()
" + data + # Non-english characters are not displaying correctly. + # This is a bug in CEF. A quick fix is to get the charset + # from response headers and insert into + # the html page. + # Bug reported on the CEF C++ Forum: + # http://www.magpcss.org/ceforum/viewtopic.php?p=18401#p18401 + if FIX_ENCODING_BUG: + contentType = response.GetHeader("Content-Type") + if contentType: + contentType = contentType.lower() + isHtml = False + headerCharset = "" + if contentType and "text/html" in contentType: + isHtml = True + if contentType and "charset" in contentType: + match = re.search(r"charset\s*=\s*([^\s]+)", contentType) + if match and match.group(1): + headerCharset = match.group(1).lower() + if isHtml and headerCharset \ + and headerCharset != BROWSER_DEFAULT_ENCODING.lower(): + if not re.search(r"]+charset\s*=", data, \ + re.IGNORECASE): + # Only apply the fix if there is no + # available on a page. + data = ("" % headerCharset) + data + return data + + # A strong reference to ResourceHandler must be kept + # during the request. Some helper functions for that. + # 1. Add reference in GetResourceHandler() + # 2. Release reference in ResourceHandler.ReadResponse() + # after request is completed. + + _resourceHandlers = {} + _resourceHandlerMaxId = 0 + + def _AddStrongReference(self, resHandler): + self._resourceHandlerMaxId += 1 + resHandler._resourceHandlerId = self._resourceHandlerMaxId + self._resourceHandlers[resHandler._resourceHandlerId] = resHandler + + def _ReleaseStrongReference(self, resHandler): + if resHandler._resourceHandlerId in self._resourceHandlers: + del self._resourceHandlers[resHandler._resourceHandlerId] + else: + print("_ReleaseStrongReference() FAILED: resource handler " \ + "not found, id = %s" % (resHandler._resourceHandlerId)) + +class ResourceHandler: + + # The methods of this class will always be called + # on the IO thread. + + _resourceHandlerId = None + _clientHandler = None + _browser = None + _frame = None + _request = None + _responseHeadersReadyCallback = None + _webRequest = None + _webRequestClient = None + _offsetRead = 0 + + def ProcessRequest(self, request, callback): + print("ProcessRequest()") + # 1. Start the request using WebRequest + # 2. Return True to handle the request + # 3. Once response headers are ready call + # callback.Continue() + self._responseHeadersReadyCallback = callback + self._webRequestClient = WebRequestClient() + self._webRequestClient._resourceHandler = self + # Need to set AllowCacheCredentials and AllowCookies for + # the cookies to work during POST requests (Issue 127). + # To skip cache set the SkipCache request flag. + request.SetFlags(cefpython.Request.Flags["AllowCachedCredentials"]\ + | cefpython.Request.Flags["AllowCookies"]) + # A strong reference to the WebRequest object must kept. + self._webRequest = cefpython.WebRequest.Create( + request, self._webRequestClient) + return True + + def GetResponseHeaders(self, response, responseLengthOut, redirectUrlOut): + print("GetResponseHeaders()") + # 1. If the response length is not known set + # responseLengthOut[0] to -1 and ReadResponse() + # will be called until it returns False. + # 2. If the response length is known set + # responseLengthOut[0] to a positive value + # and ReadResponse() will be called until it + # returns False or the specified number of bytes + # have been read. + # 3. Use the |response| object to set the mime type, + # http status code and other optional header values. + # 4. To redirect the request to a new URL set + # redirectUrlOut[0] to the new url. + assert self._webRequestClient._response, "Response object empty" + wrcResponse = self._webRequestClient._response + response.SetStatus(wrcResponse.GetStatus()) + response.SetStatusText(wrcResponse.GetStatusText()) + response.SetMimeType(wrcResponse.GetMimeType()) + if wrcResponse.GetHeaderMultimap(): + response.SetHeaderMultimap(wrcResponse.GetHeaderMultimap()) + print("headers: ") + print(wrcResponse.GetHeaderMap()) + responseLengthOut[0] = self._webRequestClient._dataLength + if not responseLengthOut[0]: + # Probably a cached page? Or a redirect? + pass + + def ReadResponse(self, dataOut, bytesToRead, bytesReadOut, callback): + # print("ReadResponse()") + # 1. If data is available immediately copy up to + # bytesToRead bytes into dataOut[0], set + # bytesReadOut[0] to the number of bytes copied, + # and return true. + # 2. To read the data at a later time set + # bytesReadOut[0] to 0, return true and call + # callback.Continue() when the data is available. + # 3. To indicate response completion return false. + if self._offsetRead < self._webRequestClient._dataLength: + dataChunk = self._webRequestClient._data[\ + self._offsetRead:(self._offsetRead + bytesToRead)] + self._offsetRead += len(dataChunk) + dataOut[0] = dataChunk + bytesReadOut[0] = len(dataChunk) + return True + self._clientHandler._ReleaseStrongReference(self) + print("no more data, return False") + return False + + def CanGetCookie(self, cookie): + # Return true if the specified cookie can be sent + # with the request or false otherwise. If false + # is returned for any cookie then no cookies will + # be sent with the request. + return True + + def CanSetCookie(self, cookie): + # Return true if the specified cookie returned + # with the response can be set or false otherwise. + return True + + def Cancel(self): + # Request processing has been canceled. + pass + +class WebRequestClient: + + _resourceHandler = None + _data = "" + _dataLength = -1 + _response = None + + def OnUploadProgress(self, webRequest, current, total): + pass + + def OnDownloadProgress(self, webRequest, current, total): + pass + + def OnDownloadData(self, webRequest, data): + # print("OnDownloadData()") + self._data += data + + def OnRequestComplete(self, webRequest): + print("OnRequestComplete()") + # cefpython.WebRequest.Status = {"Unknown", "Success", + # "Pending", "Canceled", "Failed"} + statusText = "Unknown" + if webRequest.GetRequestStatus() in cefpython.WebRequest.Status: + statusText = cefpython.WebRequest.Status[\ + webRequest.GetRequestStatus()] + print("status = %s" % statusText) + print("error code = %s" % webRequest.GetRequestError()) + # Emulate OnResourceResponse() in ClientHandler: + self._response = webRequest.GetResponse() + # Are webRequest.GetRequest() and + # self._resourceHandler._request the same? What if + # there was a redirect, what will GetUrl() return + # for both of them? + self._data = self._resourceHandler._clientHandler._OnResourceResponse( + self._resourceHandler._browser, + self._resourceHandler._frame, + webRequest.GetRequest(), + webRequest.GetRequestStatus(), + webRequest.GetRequestError(), + webRequest.GetResponse(), + self._data) + self._dataLength = len(self._data) + # ResourceHandler.GetResponseHeaders() will get called + # after _responseHeadersReadyCallback.Continue() is called. + self._resourceHandler._responseHeadersReadyCallback.Continue() + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(800,600)) + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.mainPanel.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings={"plugins_disabled": False, + "default_encoding": BROWSER_DEFAULT_ENCODING}, + navigateUrl="file://"+GetApplicationPath("example.html")) + + clientHandler = ClientHandler() + self.browser.SetClientHandler(clientHandler) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # In wx.chromectrl calling browser.CloseBrowser() and/or + # self.Destroy() in OnClose is causing crashes when embedding + # multiple browser tabs. The solution is to call only + # browser.ParentWindowWillClose. Behavior of this example + # seems different as it extends wx.Frame, while ChromeWindow + # from chromectrl extends wx.Window. Calling CloseBrowser + # and Destroy does not cause crashes, but is not recommended. + # Call ParentWindowWillClose and event.Skip() instead. See + # also Issue 107. + self.browser.ParentWindowWillClose() + event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("wxpython.py: OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +if __name__ == '__main__': + sys.excepthook = ExceptHook + settings = { + "debug": False, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + } + # print("browser_subprocess_path="+settings["browser_subprocess_path"]) + cefpython.Initialize(settings) + print('wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/binaries_64bit/wxpython.html b/cefpython/cef3/linux/binaries_64bit/wxpython.html new file mode 100644 index 00000000..caf056ff --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/wxpython.html @@ -0,0 +1,707 @@ + + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + +Use the mouse context menu to go Back/Forward in history navigation. + +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
+ +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key which is handled in KeyboardHandler.OnKeyEvent
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python') +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)  
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ +Try this: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu to return back +here after visiting the url:
+ + https://tv.eurosport.com/do-not-allow +
+ +This url will be allowed:
+ + https://tv.eurosport.com/ + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
    + Or visit it in a js popup:
    + + javascript:window.open('http://www.html-kit.com/tools/cookietester/') +
  2. +
  3. Open cookietester in a popup:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie: +external.SetCookie() +
+ +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+ + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +Try this: + + http://www.non-existent.nono/ +

+ +Note: after you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/linux/binaries_64bit/wxpython.py b/cefpython/cef3/linux/binaries_64bit/wxpython.py new file mode 100644 index 00000000..2ad47bc9 --- /dev/null +++ b/cefpython/cef3/linux/binaries_64bit/wxpython.py @@ -0,0 +1,786 @@ +# An example of embedding CEF browser in wxPython on Linux. +# Tested with wxPython 2.8.12.1 (gtk2-unicode). +# To install wxPython type "sudo apt-get install python-wxtools". + +# The official CEF Python binaries come with tcmalloc hook +# disabled. But if you've built custom binaries and kept tcmalloc +# hook enabled, then be aware that in such case it is required +# for the cefpython module to be the very first import in +# python scripts. See Issue 73 in the CEF Python Issue Tracker +# for more details. + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.so') +if os.path.exists(libcef_so): + # Import a local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect + +g_browserSettings = None + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def __init__(self, url=None): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(1024,768)) + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.mainPanel.GetGtkWidget()) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings=g_browserSettings, + navigateUrl=url) + + clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + jsBindings.SetObject("external", JavascriptExternal(self.browser)) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # In wx.chromectrl calling browser.CloseBrowser() and/or + # self.Destroy() in OnClose is causing crashes when embedding + # multiple browser tabs. The solution is to call only + # browser.ParentWindowWillClose. Behavior of this example + # seems different as it extends wx.Frame, while ChromeWindow + # from chromectrl extends wx.Window. Calling CloseBrowser + # and Destroy does not cause crashes, but is not recommended. + # Call ParentWindowWillClose and event.Skip() instead. See + # also Issue 107. + self.browser.ParentWindowWillClose() + event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def CreateAnotherBrowser(self, url=None): + """ + TODO: There are errors in the console when closing the window: + >> Check failed: window + >> Gdk: _gdk_window_destroy_hierarchy: assertion `GDK_IS_WINDOW\ + >> (window)' failed + >> GLib-GObject: g_object_unref: assertion `G_IS_OBJECT (object)' failed + """ + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.GetMainFrame().ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s"\ + % event["focus_on_editable_field"]) + if platform.system() == "Linux": + # F5 + if event["native_key_code"] == 71: + print("[wxpython.py] F5 pressed, calling"\ + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if event["native_key_code"] == 9: + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if event["native_key_code"] == 96: + print("[wxpython.py] F12 pressed, calling"\ + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + elif platform.system() == "Windows": + # F5 todo + # Escape todo + pass + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl.startswith( + "https://tv.eurosport.com/do-not-allow"): + print(" Not allowed!") + return False + if requestUrl.startswith( + "https://tv.eurosport.com/"): + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load"\ + " error: Esc was pressed or file download was aborted") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName,\ + popupFeatures, windowInfo, client, browserSettings,\ + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + allowPopups = True + return not allowPopups + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("[wxpython.py] OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + +if __name__ == '__main__': + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + # These directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + "downloads_enabled": True, + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": False, + } + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "remote-debugging-port": "12345", + # "disable-gpu": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = MyApp(False) + app.MainLoop() + # Let wx.App destructor do the cleanup before calling cefpython.Shutdown(). + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/linux/compile.py b/cefpython/cef3/linux/compile.py new file mode 100644 index 00000000..609ae3f8 --- /dev/null +++ b/cefpython/cef3/linux/compile.py @@ -0,0 +1,163 @@ +import sys +import os +import glob +import shutil +import subprocess +import platform +import stat +import re + +# This will not show "Segmentation fault" error message: +# | subprocess.call(["python", "./wxpython.py"]) +# You need to call it with shell=True for this kind of +# error message to be shown: +# | subprocess.call("python wxpython.py", shell=True) + +# How to debug: +# 1. Install "python-dbg" package +# 2. Install "python-wxgtk2.8-dbg" package +# 3. Run "python compile.py debug" +# 4. In cygdb type "cy run" +# 5. To display debug backtrace type "cy bt" +# 6. More commands: http://docs.cython.org/src/userguide/debugging.html + +if len(sys.argv) > 1 and "--debug" in sys.argv: + DEBUG = True + print("DEBUG mode On") +else: + DEBUG = False + +if len(sys.argv) > 1 and re.search(r"^\d+\.\d+$", sys.argv[1]): + VERSION = sys.argv[1] +else: + print("[compile.py] ERROR: expected first argument to be version number") + print(" Allowed version format: \\d+\.\\d+") + sys.exit(1) + +print("VERSION=%s"%VERSION) + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +PYVERSION = str(sys.version_info[0])+str(sys.version_info[1]) +print("PYVERSION = %s" % PYVERSION) +print("BITS = %s" % BITS) + +print("Compiling C++ projects") + +# Need to allow continuing even when make fails, as it may +# fail because the "public" function declaration is not yet +# in "cefpython.h", but for it to be generated we need to run +# cython compiling, so in this case you continue even when make +# fails and then run the compile.py script again and this time +# make should succeed. + +os.chdir("./../../cpp_utils/") +subprocess.call("rm -f *.o *.a", shell=True) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +os.chdir("./../cef3/client_handler/") +subprocess.call("rm -f *.o *.a", shell=True) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +os.chdir("./../subprocess/") +subprocess.call("rm -f *.o *.a", shell=True) +subprocess.call("rm -f subprocess", shell=True) + +ret = subprocess.call("make -f Makefile-libcefpythonapp", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) +subprocess_exe = "./../linux/binaries_%s/subprocess" % (BITS) +if os.path.exists("./subprocess"): + # .copy() will also copy Permission bits + shutil.copy("./subprocess", subprocess_exe) + +# os.chdir("./../v8function_handler/") +# ret = subprocess.call("make -f Makefile", shell=True) +# if ret != 0: +# what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") +# if what != "y": +# sys.exit(1) + +os.chdir("./../linux/") + +try: + os.remove("./binaries_%s/cefpython_py%s.so" % (BITS, PYVERSION)) +except OSError: + pass + +os.system("rm ./setup/cefpython_py*.so") + +pyx_files = glob.glob("./setup/*.pyx") +for f in pyx_files: + os.remove(f) + +try: + shutil.rmtree("./setup/build") +except OSError: + pass + +os.chdir("./setup") + +ret = subprocess.call("python fix_pyx_files.py", shell=True) +if ret != 0: + sys.exit("ERROR") + +# Create __version__.pyx after fix_pyx_files.py was called, +# as that script deletes old pyx files before copying new ones. +print("Creating __version__.pyx file") +with open("__version__.pyx", "w") as fo: + fo.write('__version__ = "{}"\n'.format(VERSION)) + +if DEBUG: + ret = subprocess.call("python-dbg setup.py build_ext --inplace" + " --cython-gdb", shell=True) +else: + ret = subprocess.call("python setup.py build_ext --inplace", shell=True) + +if DEBUG: + shutil.rmtree("./../binaries_%s/cython_debug/" % BITS, ignore_errors=True) + shutil.copytree("./cython_debug/", "./../binaries_%s/cython_debug/" % BITS) + +os.chdir("../") + +oldpyxfiles = glob.glob("./setup/*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +if ret != 0: + sys.exit("ERROR") + +exitcode = os.system("mv ./setup/cefpython_py{0}*.so" + " ./binaries_{1}/cefpython_py{0}.so" + .format(PYVERSION, BITS)) +if exitcode: + raise RuntimeError("Failed to move the cefpython module") + +print("DONE") + +os.chdir("./binaries_%s" % BITS) +if DEBUG: + subprocess.call("cygdb . --args python-dbg wxpython.py", shell=True) +else: + subprocess.call("python wxpython.py", shell=True) diff --git a/cefpython/cef3/linux/installer/.gitignore b/cefpython/cef3/linux/installer/.gitignore new file mode 100644 index 00000000..c1000e0a --- /dev/null +++ b/cefpython/cef3/linux/installer/.gitignore @@ -0,0 +1,2 @@ +/cefpython3-*/ +/deb_archive/ diff --git a/cefpython/cef3/linux/installer/README.txt b/cefpython/cef3/linux/installer/README.txt new file mode 100644 index 00000000..8b481c2a --- /dev/null +++ b/cefpython/cef3/linux/installer/README.txt @@ -0,0 +1,20 @@ +1. To install CEF Python 3 package type: + + sudo python setup.py install + + This will install the cefpython3 package to + /usr/local/lib/python2.7/dist-packages/ + +2. In the same directory that setup.py resides there is + an examples/ directory. Run some examples from there: + + cd examples/ + python pygtk_.py + python pyqt.py + python wxpython.py + python kivy_.py + + cd wx/ + python sample1.py + python sample2.py + python sample3.py diff --git a/cefpython/cef3/linux/installer/__init__.py.template b/cefpython/cef3/linux/installer/__init__.py.template new file mode 100644 index 00000000..80cb8605 --- /dev/null +++ b/cefpython/cef3/linux/installer/__init__.py.template @@ -0,0 +1,34 @@ +__all__ = ["cefpython", "wx"] +__version__ = "%(APP_VERSION)s" +__author__ = "The CEF Python authors" + +import ctypes, os + +# If this is a debian package then package_dir returns: +# /usr/lib/pymodules/python2.7/cefpython3 +# The above path consists of symbolic links to the real directory: +# /usr/share/pyshared/cefpython3 + +# If package was installed using PIP or setup.py then package +# dir is here: +# /usr/local/lib/python2.7/dist-packages/cefpython3/ + +package_dir = os.path.dirname(os.path.abspath(__file__)) + +# This loads the libcef.so library for the subprocess executable. +os.environ["LD_LIBRARY_PATH"] = package_dir + +# This env variable will be returned by cefpython.GetModuleDirectory(). +os.environ["CEFPYTHON3_PATH"] = package_dir + +# This loads the libcef.so library for the main python executable. +# The libffmpegsumo.so library does not need to be loaded here, +# it may cause issues to load it here in the browser process. +libcef_so = os.path.join(package_dir, "libcef.so") +ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + +import sys +if 0x02070000 <= sys.hexversion < 0x03000000: + from . import cefpython_py27 as cefpython +else: + raise Exception("Unsupported python version: " + sys.version) diff --git a/cefpython/cef3/linux/installer/build-n-run-wx-chromectrl.sh b/cefpython/cef3/linux/installer/build-n-run-wx-chromectrl.sh new file mode 100755 index 00000000..dc34e6d2 --- /dev/null +++ b/cefpython/cef3/linux/installer/build-n-run-wx-chromectrl.sh @@ -0,0 +1,7 @@ +set -o verbose +sudo rm -rf cefpython3-31.0-linux-64bit-setup/ +python make-setup.py -v 31.0 +cd cefpython3-31.0-linux-64bit-setup/ +sudo python setup.py install +cd examples/wx/ +python sample1.py diff --git a/cefpython/cef3/linux/installer/debian.postinst b/cefpython/cef3/linux/installer/debian.postinst new file mode 100644 index 00000000..51d693f3 --- /dev/null +++ b/cefpython/cef3/linux/installer/debian.postinst @@ -0,0 +1,44 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -e + +# Permissions for the executable files +chmod 755 /usr/share/pyshared/cefpython3/cefclient +chmod 755 /usr/share/pyshared/cefpython3/subprocess + +# Permissions for the examples - debug.log is created. +# If you want to run the cefclient executable you may +# also have to chmod 777 /usr/share/pyshared/cefpython3/. +chmod 666 /usr/share/pyshared/cefpython3/debug.log +chmod 666 /usr/share/pyshared/cefpython3/examples/debug.log +chmod 666 /usr/share/pyshared/cefpython3/examples/wx/debug.log + +# Check if libudev.so.0 exists and if not, create +# a symbolic link to libudev.so.1. See issues 145 +# and 105 in the CEFPython Issue Tracker. +# -- Sequence of these dirs does matter, on first +# -- match searching should be stopped. +declare -a libdirs=("/lib/x86_64-linux-gnu" "/usr/lib64" + "/lib/i386-linux-gnu" "/usr/lib") +for libdir in "${libdirs[@]}" +do + libudev_1="$libdir/libudev.so.1" + libudev_0="$libdir/libudev.so.0" + if [ -f $libudev_1 ] && ! [ -f $libudev_0 ]; + then + echo "ln -sf $libudev_1 $libudev_0" + ln -sf "$libudev_1" "$libudev_0" + break + fi +done + +# This creates symbolic links in /usr/lib/pymodules/.../cefpython3/ +# for all the files. This is no more required, as in make-deb.py +# we're modify the deb archive and moving the /usr/lib/pyshared/.../ +# .so files to the /usr/share/pyshared/.../ directory. Read the +# comments in make-deb.py why it needs to be done so. +# Let's keep the creation of symlinks for backwards compatibility. +if which update-python-modules >/dev/null 2>&1; then + update-python-modules python-cefpython3.public +fi diff --git a/cefpython/cef3/linux/installer/deps.txt b/cefpython/cef3/linux/installer/deps.txt new file mode 100644 index 00000000..0920a362 --- /dev/null +++ b/cefpython/cef3/linux/installer/deps.txt @@ -0,0 +1,30 @@ +gconf-service +libasound2 (>= 1.0.23) +libatk1.0-0 (>= 1.12.4) +libc6 (>= 2.11) +libcairo2 (>= 1.6.0) +libcap2 (>= 2.10) +libcups2 (>= 1.4.0) +libdbus-1-3 (>= 1.2.14) +libexpat1 (>= 1.95.8) +libfontconfig1 (>= 2.8.0) +libfreetype6 (>= 2.3.9) +libgcc1 (>= 1:4.1.1) +libgconf-2-4 (>= 2.31.1) +libgcrypt11 (>= 1.4.5) +libgdk-pixbuf2.0-0 (>= 2.22.0) +libglib2.0-0 (>= 2.18.0) +libgtk2.0-0 (>= 2.24.0) +libnspr4 (>= 1.8.0.10) +libnss3 (>= 3.14.3) +libpango1.0-0 (>= 1.22.0) +libstdc++6 (>= 4.6) +libx11-6 (>= 2:1.4.99.1) +libxcomposite1 (>= 1:0.3-1) +libxdamage1 (>= 1:1.1) +libxext6 +libxfixes3 +libxi6 (>= 2:1.2.99.4) +libxrender1 +libxss1 +libxtst6 \ No newline at end of file diff --git a/cefpython/cef3/linux/installer/find-deps.py b/cefpython/cef3/linux/installer/find-deps.py new file mode 100644 index 00000000..67e2e0ca --- /dev/null +++ b/cefpython/cef3/linux/installer/find-deps.py @@ -0,0 +1,217 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# This script finds dependencies. It fetches google chrome +# debian package dependencies from src.chromium.org for +# specific revision. Filters these dependencies with data +# returned by ldd command. Saves results to deps.txt. + +import os +import sys +import re +import platform +import glob +import subprocess + +def main(): + branch = get_branch() + revision = get_chromium_revision(branch) + chrome_deps = get_chrome_deps(revision) + cef_library_dependencies = get_cef_library_dependencies() + cef_deps = get_cef_deps(cef_library_dependencies) + final_deps = get_final_deps(chrome_deps, cef_deps) + curdir = os.path.dirname(os.path.realpath(__file__)) + with open(curdir+"/deps.txt", "w") as f: + f.write("\n".join(final_deps)) + log("Saved deps to deps.txt file") + success = check_final_deps(final_deps) + if not success: + sys.exit(1) + +def log(msg): + print("[dependencies.py] %s" % msg) + +def fetch_url(url): + if sys.version_info[0] == 2: + import urllib2 + try: + urlfile = urllib2.urlopen(url) + except: + # 404 for example + return None + return urlfile.read() + else: + import urllib.request + try: + urlfile = urllib.request.urlopen(url) + except: + # 404 for example + return None + return urlfile.read() + +def get_branch(): + curdir = os.path.dirname(os.path.realpath(__file__)) + with open(curdir+"/../../BUILD_COMPATIBILITY.txt") as f: + m = re.search(r"\d+\.\d+\.(\d+)\.\d+", f.read()) + branch = m.group(1) + log("branch = %s" % branch) + return branch + +def get_chromium_revision(branch): + url = "http://src.chromium.org/viewvc" \ + "/chrome/branches/%s/src/chrome/VERSION" % branch + contents = fetch_url(url) + if not contents: + raise Exception("Failed fetching url: %s" % url) + m = re.search(r"revision=(\d+)", contents) + revision = m.group(1) + log("chromium revision = %s" % revision) + return revision + +def get_chrome_deps(revision): + # Currently works only with SVN up to Chrome revision 293233. + base_url = "http://src.chromium.org/svn/trunk/src" \ + "/chrome/installer/linux/debian" + url = base_url+"/expected_deps?p=%s" % revision + contents = fetch_url(url) + if not contents: + url = base_url+"/expected_deps_x64?p=%s" % revision + contents = fetch_url(url) + if not contents: + raise Exception("Failed fetching url: %s" % url) + contents = contents.strip() + deps = contents.splitlines() + for i, dep in enumerate(deps): + deps[i] = dep.strip() + deps.sort(key = lambda s: s.lower()); + log("Found %d Chrome deps" % len(deps)) + print("-" * 80) + print("\n".join(deps)) + print("-" * 80) + return deps + +def get_cef_library_dependencies(): + # Chrome deps != library dependencies + # deps = package dependencies (for apt-get install) + # library dependencies -> a package with such name may not exist + curdir = os.path.dirname(os.path.realpath(__file__)) + bits = platform.architecture()[0] + assert (bits == "32bit" or bits == "64bit") + binaries_dir = curdir+"/../binaries_%s" % bits + libraries = glob.glob(binaries_dir+"/*.so") + assert(len(libraries)) + log("Found %d CEF libraries" % (len(libraries))) + all_dependencies = [] + for library in libraries: + library = os.path.abspath(library) + dependencies = get_library_dependencies(library) + all_dependencies = all_dependencies + dependencies + all_dependencies = remove_duplicate_dependencies(all_dependencies) + log("Found %d all CEF library dependencies combined" \ + % len(all_dependencies)) + return all_dependencies + +def remove_duplicate_dependencies(dependencies): + unique = [] + for dependency in dependencies: + if dependency not in unique: + unique.append(dependency) + return unique + +def get_library_dependencies(library): + contents = subprocess.check_output("ldd %s" % library, shell=True) + contents = contents.strip() + lines = contents.splitlines() + dependencies = [] + for line in lines: + m = re.search(r"([^/\s=>]+).so[.\s]", line) + dependencies.append(m.group(1)) + dependencies.sort(key = lambda s: s.lower()); + log("Found %d dependencies in %s:" % \ + (len(dependencies), os.path.basename(library))) + print("-" * 80) + print("\n".join(dependencies)) + print("-" * 80) + return dependencies + +def get_cef_deps(dependencies): + cef_deps = [] + for dependency in dependencies: + if package_exists(dependency): + cef_deps.append(dependency) + log("Found %d CEF deps for which package exists:" % len(cef_deps)) + print("-" * 80) + print("\n".join(cef_deps)) + print("-" * 80) + return cef_deps + +def package_exists(package): + try: + devnull = open('/dev/null', 'w') + contents = subprocess.check_output("dpkg -s %s" % package, + stderr=devnull, shell=True) + devnull.close() + except subprocess.CalledProcessError, e: + return False + if "install ok installed" in contents: + return True + print("**PROBABLY ERROR OCCURED** while calling: %s" % "dpkg -s "+package) + return False + +def get_final_deps(chrome_deps, cef_deps): + final_deps = chrome_deps + chrome_deps_names = [] + chrome_libudev0_dep = "" + for chrome_dep in chrome_deps: + chrome_dep_name = get_chrome_dep_name(chrome_dep) + chrome_deps_names.append(chrome_dep_name) + if chrome_dep_name == "libudev0": + chrome_libudev0_dep = chrome_dep + for cef_dep in cef_deps: + if cef_dep not in chrome_deps_names: + final_deps.append(cef_dep) + log("Found %d CEF deps that were not listed in Chrome deps" % \ + (len(final_deps)-len(chrome_deps)) ) + # See Issue 145. libudev.so.0 may be missing and postinstall + # script creates a symlink. Not sure how Google Chrome can + # have libudev0 in deps and deb package can install fine. + if chrome_libudev0_dep and chrome_libudev0_dep in final_deps: + log("Removing '%s' from final deps (Issue 145)" % chrome_libudev0_dep) + final_deps.remove(chrome_libudev0_dep) + if "libudev0" in final_deps: + log("Removing 'libudev0' from final deps (Issue 145)") + final_deps.remove("libudev0") + log("Found %d final deps:" % len(final_deps)) + print("-" * 80) + print("\n".join(final_deps)) + print("-" * 80) + return final_deps + +def get_chrome_dep_name(dep): + # Eg. libxcomposite1 (>= 1:0.3-1) ===> libxcomposite1 + dep = re.sub(r"\([^\(]+\)", "", dep) + dep = dep.strip() + return dep + +def check_final_deps(deps): + # Check if all deps packages are installed + deps_not_installed = [] + for dep in deps: + dep_name = get_chrome_dep_name(dep) + if not package_exists(dep_name): + deps_not_installed.append(dep_name) + if len(deps_not_installed) == 0: + log("Everything is OK. All deps are found to be installed.") + return True + else: + log("Found %d deps that are currently not installed:" % \ + len(deps_not_installed)) + print("-" * 80) + print("\n".join(deps_not_installed)) + print("-" * 80) + log("ERROR") + return False + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/linux/installer/make-deb.py b/cefpython/cef3/linux/installer/make-deb.py new file mode 100644 index 00000000..24007c72 --- /dev/null +++ b/cefpython/cef3/linux/installer/make-deb.py @@ -0,0 +1,332 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +""" +Create a Debian Package. + +Required dependencies: + sudo apt-get install python-support + sudo apt-get install python-pip + sudo pip install stdeb==0.6.0 +""" + +import subprocess +import os, sys +import platform +import argparse +import re +import shutil + +# ----------------------------------------------------------------------------- +# Globals + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") +ARCHITECTURE = "i386" if (BITS == "32bit") else "amd64" +if BITS == "32bit": + LINUX_BITS = "linux32" +else: + LINUX_BITS = "linux64" + +PACKAGE_NAME = "cefpython3" +PYTHON_NAME ="python2.7" # Directory name in deb archive + +HOMEPAGE = "https://code.google.com/p/cefpython/" +MAINTAINER = "Czarek Tomczak " +DESCRIPTION_EXTENDED = \ +""" CEF Python 3 is a python library for embedding the Chromium + browser. It uses the Chromium Embedded Framework (CEF) internally. + Examples of embedding are available for many GUI toolkits, + including wxPython, PyGTK, PyQt, PySide, Kivy and PyWin32. +""" + +COPYRIGHT = \ +"""Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Name: cefpython3 +Maintainer: %s +Source: %s + +Copyright: 2012-2014 The CEF Python authors +License: BSD 3-Clause + +Files: * +Copyright: 2012-2014 The CEF Python authors +License: BSD 3-Clause +""" % (MAINTAINER, HOMEPAGE) + +PYTHON_VERSION_WITH_DOT = (str(sys.version_info.major) + "." + + str(sys.version_info.minor)) + +VERSION = None + +# cefpython/cef3/linux/installer +INSTALLER = os.path.dirname(os.path.abspath(__file__)) + +# installer/cefpython3-31.0-linux-64bit-setup/ +DISTUTILS_SETUP = None + +# deb_dist/ +DEB_DIST = None + +# deb_dist/cefpython3-31.0/ +DEB_DIST_PACKAGE = None + +# deb_dist/cefpython3-31.0/debian/ +DEBIAN = None + +# deb_dist/cefpython3-31.0/debian/python-cefpython3/ +DEBIAN_PACKAGE = None + +# ----------------------------------------------------------------------------- + +def log(msg): + print("[make-deb.py] %s" % msg) + +def replace_in_file(f_path, s_what, s_with): + contents = "" + with open(f_path, "r") as f: + contents = f.read() + assert contents, ("Failed reading file: %s" % f_path) + contents = contents.replace(s_what, s_with) + with open(f_path, "w") as f: + f.write(contents) + +def remove_directories_from_previous_run(): + if os.path.exists(DISTUTILS_SETUP): + log("The Distutils setup directory already exists, removing..") + shutil.rmtree(DISTUTILS_SETUP) + + if os.path.exists(INSTALLER+"/deb_dist/"): + log("The deb_dist/ directory already exists, removing..") + shutil.rmtree(INSTALLER+"/deb_dist/") + + if os.path.exists(INSTALLER+"/deb_archive/"): + log("The deb_archive/ directory already exists, removing..") + shutil.rmtree(INSTALLER+"/deb_archive/") + +def create_distutils_setup_package(): + log("Creating Distutils setup package") + subprocess.call("%s %s/make-setup.py -v %s" % \ + (sys.executable, INSTALLER, VERSION), shell=True) + assert os.path.exists(DISTUTILS_SETUP),\ + "Distutils Setup directory not found" + +def modify_control_file(): + log("Modyfing debian control file") + control_file = DEBIAN+"/control" + + # Read contents + with open(control_file, "r") as f: + contents = f.read() + + # Set architecture to i386 or amd64 + contents = contents.replace("Architecture: all", + "Architecture: %s" % ARCHITECTURE) + + # Extend the Package section, remove the two ending new lines + contents = re.sub("[\r\n]+$", "", contents) + contents += "\n" + + # Extend description + description = DESCRIPTION_EXTENDED + description = re.sub("[\r\n]+", "\n", description) + description = re.sub("\n$", "", description) + contents += "%s\n" % description + + # Other fields + contents += "Version: %s-1\n" % VERSION + contents += "Maintainer: %s\n" % MAINTAINER + contents += "Homepage: %s\n" % HOMEPAGE + + # Control file should end with two new lines + contents += "\n" + with open(control_file, "w") as f: + f.write(contents) + +def create_copyright_file(): + # The license is "Unknown" when opening deb package in + # Ubuntu Software Center. It's a known bug: + # https://bugs.launchpad.net/ubuntu/+source/software-center/+bug/435183 + log("Creating debian copyright file") + copyright = COPYRIGHT + copyright = re.sub("[\r\n]", "\n", copyright) + copyright += "\n" + copyright += "License: BSD 3-clause\n" + with open(INSTALLER+"/../../../LICENSE.txt", "r") as f: + license = f.readlines() + for line in license: + if not len(re.sub("\s+", "", line)): + copyright += " .\n" + else: + copyright += " "+line.rstrip()+"\n" + copyright += "\n" + with open(DEBIAN+"/copyright", "w") as f: + f.write(copyright) + +def copy_postinst_script(): + # When creating .postinst file in the debian directory, + # it will overwrite the default postinst script created + # by dh_pysupport, its contents are: + # ----------------------------------------------------- + # if which update-python-modules >/dev/null 2>&1; then + # update-python-modules python-cefpython3.public + # fi + # ----------------------------------------------------- + # The command above creates symlinks for libraries and + # executables, so that they appear to be in one directory. + # CEF executable requires that libcef.so and the subprocess + # executable are in the same directory. + # This solution does not to work correctly in CEF3 branch + # 1650, so we will have to put .so libraries along with + # other files in a real single directory. + log("Copying .postinst script") + shutil.copy(INSTALLER+"/debian.postinst", + DEBIAN+"/python-%s.postinst" % (PACKAGE_NAME)) + +def create_debian_source_package(): + log("Creating Debian source package using stdeb") + os.chdir(DISTUTILS_SETUP) + shutil.copy("../stdeb.cfg.template", "stdeb.cfg") + stdeb_cfg_add_deps("stdeb.cfg") + subprocess.call("%s setup.py --command-packages=stdeb.command sdist_dsc"\ + % (sys.executable,), shell=True) + +def stdeb_cfg_add_deps(stdeb_cfg): + log("Adding deps to stdeb.cfg") + with open(INSTALLER+"/deps.txt", "r") as f: + deps = f.read() + deps = deps.strip() + deps = deps.splitlines() + for i, dep in enumerate(deps): + deps[i] = dep.strip() + deps = ", ".join(deps) + with open(stdeb_cfg, "a") as f: + f.write("\nDepends: %s" % deps) + +def deb_dist_cleanup(): + # Move the deb_dist/ directory and remove unnecessary files + log("Preparing the deb_dist directory") + os.system("mv %s %s"\ + % (DISTUTILS_SETUP+"/deb_dist", INSTALLER+"/deb_dist")) + os.system("rm -rf %s" % DISTUTILS_SETUP) + # Paths + global DEB_DIST, DEB_DIST_PACKAGE, DEBIAN, DEBIAN_PACKAGE + DEB_DIST = INSTALLER+"/deb_dist" + DEB_DIST_PACKAGE = DEB_DIST+"/"+PACKAGE_NAME+"-"+VERSION + DEBIAN = DEB_DIST_PACKAGE+"/debian" + DEBIAN_PACKAGE = DEBIAN+"/python-"+PACKAGE_NAME + # Remove unnecessary files + os.chdir(DEB_DIST) + os.system("rm *.gz") + os.system("rm *.dsc") + +def create_debian_binary_package(): + os.chdir(DEB_DIST_PACKAGE) + # Will create .deb .dsc .gz in the upper directory DEB_DIST + subprocess.call("dpkg-buildpackage -rfakeroot -uc -us", shell=True) + +def modify_deb_archive(): + # CEF branch 1650 doesn't work when the .so files do not reside + # in the same directory as the subprocess executable. The symlinks + # created in /usr/lib/pymodules/ do not help. After launching + # CEF and webpage being displayed, the CEF renderer process + # crashes after a moment. The solution is to modify the deb + # archive, move the /usr/lib/pyshared/.../*.so libraries to + # the /usr/share/pyshared/.../ directory. Also some files with + # hardcoded paths to /usr/lub/pyshared/ need to be modified + # (eg. DEBIAN/md5sums, python-support/python-cefpython3.public). + log("Modifying the deb archive") + + # Paths + deb_archive_name = "python-%s_%s-1_%s.deb" \ + % (PACKAGE_NAME, VERSION, ARCHITECTURE) + deb_archive_dir = INSTALLER+"/deb_archive" + + # Move the deb archive to the deb_archive/ directory + log("Moving the deb archive") + os.system("mkdir %s" % deb_archive_dir) + os.system("mv %s %s" % (DEB_DIST+"/"+deb_archive_name,\ + deb_archive_dir+"/"+deb_archive_name)) + + # Remove the deb_dist/ directory + os.system("rm -rf %s" % DEB_DIST) + + # Extract the deb archive + log("Extracting the deb archive") + os.chdir(deb_archive_dir) + # Extract the usr/ directory + os.system("dpkg-deb -x %s ." % deb_archive_name) + # Extract the DEBIAN/ directory + os.system("dpkg-deb -e %s" % deb_archive_name) + + # Remove the deb archive that was extracted + os.system("rm %s" % deb_archive_name) + + # Move the .so files from the ./usr/lib/pyshared/.../ directory + # to the ./usr/share/pyshared/.../ directory. Also remove the + # ./usr/lib/ directory. + log("Moving the .so libraries") + lib_pyshared = "./usr/lib/pyshared/%s/%s" \ + % (PYTHON_NAME, PACKAGE_NAME) + share_pyshared = "./usr/share/pyshared/%s" % PACKAGE_NAME + os.system("mv %s/*.so %s/" % (lib_pyshared, share_pyshared)) + os.system("rm -rf ./usr/lib/") + + # Modify also the paths in some text files. + # The paths do not start with "/" on purpose. In the md5sums + # file the paths are relative. In the python-cefpython3.public + # file paths are absolute. + log("Modifying paths in the text files") + old_path = "usr/lib/pyshared/%s/%s/" % (PYTHON_NAME, PACKAGE_NAME) + new_path = "usr/share/pyshared/%s/" % PACKAGE_NAME + md5sums_file = "./DEBIAN/md5sums" + cefpython3_public_file = "./usr/share/python-support/python-%s.public" \ + % PACKAGE_NAME + old_md5sum = subprocess.check_output("md5sum %s | cut -c 1-32" \ + % cefpython3_public_file, shell=True).strip() + # Modify paths in the text files + replace_in_file(md5sums_file, old_path, new_path) + replace_in_file(cefpython3_public_file, old_path, new_path) + # Correct md5 sum for the python-cefpython3.public file + new_md5sum = subprocess.check_output("md5sum %s | cut -c 1-32" \ + % cefpython3_public_file, shell=True).strip() + replace_in_file(md5sums_file, old_md5sum, new_md5sum) + + # Create deb archive from the modified ./DEBIAN/ and + # ./usr/ directories. + log("Creating deb archive from the modified files") + os.system("fakeroot dpkg-deb -b . ./%s" % deb_archive_name) + +def main(): + # Command line options + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + # Version + global VERSION + VERSION = args.version + + # Paths + global DISTUTILS_SETUP + DISTUTILS_SETUP = INSTALLER+"/"+PACKAGE_NAME+"-"+args.version+"-"+\ + LINUX_BITS+"-setup" + + remove_directories_from_previous_run() + create_distutils_setup_package() + create_debian_source_package() + deb_dist_cleanup() + modify_control_file() + create_copyright_file() + copy_postinst_script() + create_debian_binary_package() + modify_deb_archive() + + log("DONE") + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/linux/installer/make-setup.py b/cefpython/cef3/linux/installer/make-setup.py new file mode 100644 index 00000000..2773f8a6 --- /dev/null +++ b/cefpython/cef3/linux/installer/make-setup.py @@ -0,0 +1,170 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a setup package. + +import sys +import os +import platform +import argparse +import re +import platform +import shutil +import glob +import sysconfig +import subprocess + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") +if BITS == "32bit": + LINUX_BITS = "linux32" +else: + LINUX_BITS = "linux64" +PACKAGE_NAME = "cefpython3" + +README_FILE = os.getcwd()+r"/README.txt" +INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template" +SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template" +SETUP_CFG_TEMPLATE = os.getcwd()+r"/setup.cfg.template" + +def str_format(string, dictionary): + orig_string = string + for key, value in dictionary.iteritems(): + string = string.replace("%("+key+")s", value) + if string == orig_string: + raise Exception("Nothing to format") + if re.search(r"%\([a-zA-Z0-9_]+\)s", string): + raise Exception("Not all strings formatted") + return string + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + vars = {} + vars["APP_VERSION"] = args.version + vars["PLATFORM"] = sysconfig.get_platform() + vars["PY_VERSION_DIGITS_ONLY"] = (str(sys.version_info.major) + "" + + str(sys.version_info.minor)) # "27" or "34" + + print("Reading template: %s" % README_FILE) + f = open(README_FILE) + README_CONTENT = f.read() + f.close() + + print("Reading template: %s" % INIT_TEMPLATE) + f = open(INIT_TEMPLATE) + INIT_CONTENT = str_format(f.read(), vars) + f.close() + + print("Reading template: %s" % SETUP_TEMPLATE) + f = open(SETUP_TEMPLATE) + SETUP_CONTENT = str_format(f.read(), vars) + f.close() + + print("Reading template: %s" % SETUP_CFG_TEMPLATE) + f = open(SETUP_CFG_TEMPLATE) + SETUP_CFG_CONTENT = str_format(f.read(), vars) + f.close() + + installer_dir = os.path.dirname(os.path.abspath(__file__)) + + setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]+"-"+LINUX_BITS+"-setup" + print("Creating setup dir: "+setup_dir) + os.mkdir(setup_dir) + + package_dir = setup_dir+"/"+PACKAGE_NAME + print("Creating package dir") + os.mkdir(package_dir) + + print("Creating README.txt from template") + with open(setup_dir+"/README.txt", "w") as f: + f.write(README_CONTENT) + + print("Creating setup.py from template") + with open(setup_dir+"/setup.py", "w") as f: + f.write(SETUP_CONTENT) + + print("Creating setup.cfg from template") + with open(setup_dir+"/setup.cfg", "w") as f: + f.write(SETUP_CFG_CONTENT) + + binaries_dir = os.path.abspath(installer_dir+"/../binaries_"+BITS+"/") + print("Copying binaries to package dir") + ret = os.system("cp -rf "+binaries_dir+"/* "+package_dir) + assert ret == 0 + + os.chdir(package_dir) + print("Removing .log files from the package dir") + ret = os.system("rm *.log") + # assert ret == 0 - if there are no .log files this assert would fail. + os.chdir(installer_dir) + + print("Creating __init__.py from template") + with open(package_dir+"/__init__.py", "w") as f: + f.write(INIT_CONTENT) + + print("Creating examples dir in package dir") + os.mkdir(package_dir+"/examples/") + + print("Moving kivy-select-boxes dir to examples dir") + shutil.move(package_dir+"/kivy-select-boxes", + package_dir+"/examples/kivy-select-boxes") + + #kivy_select_boxes_dir = package_dir+"/examples/kivy-select-boxes/" + #ret = os.system("cp -rf "+kivy_select_boxes_dir+"/* "+package_dir+"/wx/") + #assert ret == 0 + + print("Creating wx dir in package dir") + os.mkdir(package_dir+"/wx/") + + print("Moving example scripts from package dir to examples dir") + examples = glob.glob(package_dir+"/*.py") + for example in examples: + # Ignore: cefpython_py27.py - dummy API script + if os.path.basename(example).startswith("cefpython_"): + continue + # Ignore: __init__.py + if os.path.basename(example).startswith("__"): + continue + os.rename(example, package_dir+"/examples/"+os.path.basename(example)) + ret = os.system("mv "+package_dir+"/*.html "+package_dir+"/examples/") + ret = os.system("mv "+package_dir+"/*.js "+package_dir+"/examples/") + ret = os.system("mv "+package_dir+"/*.css "+package_dir+"/examples/") + assert ret == 0 + + print("Copying wx-subpackage to wx dir in package dir") + wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx-subpackage/") + ret = os.system("cp -rf "+wx_subpackage_dir+"/* "+package_dir+"/wx/") + assert ret == 0 + + print("Moving wx examples from wx/examples to examples/wx") + shutil.move(package_dir+"/wx/examples", package_dir+"/wx/wx/") + shutil.move(package_dir+"/wx/wx/", package_dir+"/examples/") + + print("Copying package dir examples to setup dir") + ret = os.system("cp -rf "+package_dir+"/examples/ "+setup_dir+"/examples/") + assert ret == 0 + + # Create empty debug.log files so that package uninstalls cleanly + # in case examples were launched. Issue 149. + debug_log_dirs = [package_dir, + package_dir+"/examples/", + package_dir+"/examples/wx/"] + for dir in debug_log_dirs: + print("Creating empty debug.log in %s" % dir) + with open(dir+"/debug.log", "w") as f: + f.write("") + # Set write permissions so that Wheel package files have it + # right. So that examples may be run from package directory. + subprocess.call("chmod 666 %s/debug.log" % dir, shell=True) + + print("Setup Package created successfully.") + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/linux/installer/setup.cfg.template b/cefpython/cef3/linux/installer/setup.cfg.template new file mode 100644 index 00000000..067dcbfd --- /dev/null +++ b/cefpython/cef3/linux/installer/setup.cfg.template @@ -0,0 +1,2 @@ +[bdist_wheel] +python-tag=cp%(PY_VERSION_DIGITS_ONLY)s diff --git a/cefpython/cef3/linux/installer/setup.py.template b/cefpython/cef3/linux/installer/setup.py.template new file mode 100644 index 00000000..db1dc063 --- /dev/null +++ b/cefpython/cef3/linux/installer/setup.py.template @@ -0,0 +1,114 @@ +try: + # The setuptools package is not installed by default + # on a clean Ubuntu. Might be also a case on Windows. + # Python Eggs and Wheels can be created only with setuptools. + from setuptools import setup + from setuptools.command.install import install as _install + from setuptools.dist import Distribution + print("[setup.py] Using setuptools") +except: + from distutils.core import setup + from distutils.command.install import install as _install + from distutils.dist import Distribution + print("[setup.py] Using distutils") + +import sys +import os +import subprocess + +def post_install(): + """ Post install tasks """ + print("[setup.py] post_install()") + + # Check if libudev.so.0 exists and if not, create + # a symbolic link to libudev.so.1. See issues 145 + # and 105 in the CEFPython Issue Tracker. + # -- Sequence of these dirs does matter, on first + # -- match searching should be stopped. + libdirs = ["/lib/x86_64-linux-gnu", "/usr/lib64", + "/lib/i386-linux-gnu", "/usr/lib"] + for libdir in libdirs: + if os.path.exists(libdir+"/libudev.so.1") \ + and not os.path.exists(libdir+"/libudev.so.0"): + libudev1 = "%s/libudev.so.1" % libdir + libudev0 = "%s/libudev.so.0" % libdir + print("[setup.py] ln -sf %s %s" % (libudev1, libudev0)) + subprocess.call("ln -sf %s %s" % (libudev1, libudev0), shell=True) + break + + # Find package directory. + # Do not import from local cefpython3/ directory. + del sys.path[0] + sys.path.append('') + import cefpython3 + package_dir = os.path.dirname(cefpython3.__file__) + + # Make sure this is not a local package imported + print("[setup.py] package_dir = %s" % package_dir) + assert not package_dir.startswith( + os.path.dirname(os.path.abspath(__file__))) + + # Execute permissions for subprocess.exe and cefclient.exe + subprocess_exe = os.path.join(package_dir, "subprocess") + cefclient_exe = os.path.join(package_dir, "cefclient") + print("[setup.py] chmod +x " + subprocess_exe) + subprocess.call("chmod +x "+subprocess_exe, shell=True) + print("[setup.py] chmod +x " + cefclient_exe) + subprocess.call("chmod +x "+cefclient_exe, shell=True) + + # Write permissions for debug.log files + commands = [ + "chmod 666 %s/debug.log" % package_dir, + "chmod 666 %s/examples/debug.log" % package_dir, + "chmod 666 %s/examples/wx/debug.log" % package_dir, + ] + for command in commands: + print("[setup.py] %s" % command) + subprocess.call(command, shell=True) + +class install(_install): + def run(self): + _install.run(self) + post_install() + +class BinaryDistribution(Distribution): + def is_pure(self): + return False + +setup( + distclass=BinaryDistribution, + cmdclass={'install': install}, + name='cefpython3', # No spaces here, so that it works with deb packages. + version='%(APP_VERSION)s', + description='Python bindings for the Chromium Embedded Framework', + license='BSD 3-Clause', + author='Czarek Tomczak', + author_email='czarek.tomczak@gmail.com', + url='http://code.google.com/p/cefpython/', + platforms=['%(PLATFORM)s'], + packages=['cefpython3', 'cefpython3.wx'], + package_data={'cefpython3': [ + 'examples/*.py', + 'examples/*.html', + 'examples/*.js', + 'examples/*.css', + 'examples/kivy-select-boxes/*.html', + 'examples/kivy-select-boxes/*.js', + 'examples/kivy-select-boxes/*.css', + 'examples/kivy-select-boxes/*.md', + 'examples/wx/*.py', + 'examples/wx/*.html', + 'examples/wx/*.png', + 'locales/*.pak', + 'wx/*.txt', + 'wx/images/*.png', + '*.txt', + 'cefclient', + 'subprocess', + '*.so', + '*.pak', + 'debug.log', + 'examples/debug.log', + 'examples/wx/debug.log', + ]} +) diff --git a/cefpython/cef3/linux/installer/stdeb.cfg.template b/cefpython/cef3/linux/installer/stdeb.cfg.template new file mode 100644 index 00000000..e1d8f310 --- /dev/null +++ b/cefpython/cef3/linux/installer/stdeb.cfg.template @@ -0,0 +1,2 @@ +[DEFAULT] +XS-Python-Version: 2.7 \ No newline at end of file diff --git a/cefpython/cef3/linux/rebuild.sh b/cefpython/cef3/linux/rebuild.sh new file mode 100755 index 00000000..f703ba9c --- /dev/null +++ b/cefpython/cef3/linux/rebuild.sh @@ -0,0 +1 @@ +python compile.py diff --git a/cefpython/cef3/linux/setup/.gitignore b/cefpython/cef3/linux/setup/.gitignore new file mode 100644 index 00000000..0882aaec --- /dev/null +++ b/cefpython/cef3/linux/setup/.gitignore @@ -0,0 +1,5 @@ +build/ +cefpython.cpp +cython_debug/ +*.pyx +*.cpp \ No newline at end of file diff --git a/cefpython/cef3/linux/setup/cefpython.h b/cefpython/cef3/linux/setup/cefpython.h new file mode 100644 index 00000000..1eb60603 --- /dev/null +++ b/cefpython/cef3/linux/setup/cefpython.h @@ -0,0 +1,93 @@ +#ifndef __PYX_HAVE__cefpython_py27 +#define __PYX_HAVE__cefpython_py27 + + +#ifndef __PYX_HAVE_API__cefpython_py27 + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +__PYX_EXTERN_C DL_IMPORT(void) PyBrowser_ShowDevTools(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) PyTaskRunnable(int); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(int, int64); +__PYX_EXTERN_C DL_IMPORT(void) V8FunctionHandler_Execute(CefRefPtr, CefRefPtr, CefString &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RemovePythonCallbacksForFrame(int); +__PYX_EXTERN_C DL_IMPORT(bool) ExecutePythonCallback(CefRefPtr, int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_OnBeforePopup(CefRefPtr, CefRefPtr, CefString const &, CefString const &, int const , CefWindowInfo &, CefRefPtr &, CefBrowserSettings &, bool *); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnAfterCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_RunModal(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_DoClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr, CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnTooltip(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnStatusMessage(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnConsoleMessage(CefRefPtr, CefString const &, CefString const &, int); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnPreKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle, bool *); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeResourceLoad(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeBrowse(CefRefPtr, CefRefPtr, CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetResourceHandler(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceRedirect(CefRefPtr, CefRefPtr, CefString const &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr, CefRefPtr, bool, CefString const &, int, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnQuotaRequest(CefRefPtr, CefString const &, int64, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetCookieManager(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnProtocolExecution(CefRefPtr, CefString const &, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforePluginLoad(CefRefPtr, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnCertificateError(int, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnRendererProcessTerminated(CefRefPtr, enum cef_termination_status_t); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnPluginCrashed(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) CookieVisitor_Visit(int, CefCookie const &, int, int, bool &); +__PYX_EXTERN_C DL_IMPORT(void) StringVisitor_Visit(int, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadingStateChange(CefRefPtr, bool, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadStart(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadEnd(CefRefPtr, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadError(CefRefPtr, CefRefPtr, enum cef_errorcode_t, CefString const &, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnRenderProcessThreadCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnBeforeChildProcessLaunch(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetRootScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetViewRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenPoint(CefRefPtr, int, int, int &, int &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenInfo(CefRefPtr, CefScreenInfo &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupShow(CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupSize(CefRefPtr, CefRect const &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPaint(CefRefPtr, cef_paint_element_type_t, std::vector &, void const *, int, int); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnCursorChange(CefRefPtr, CefCursorHandle); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnScrollOffsetChanged(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ProcessRequest(int, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_GetResponseHeaders(int, CefRefPtr, int64 &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ReadResponse(int, void *, int, int &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanGetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanSetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_Cancel(int); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnUploadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadData(int, CefRefPtr, void const *, size_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnRequestComplete(int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) App_OnBeforeCommandLineProcessing_BrowserProcess(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnJavascriptDialog(CefRefPtr, CefString const &, CefString const &, enum cef_jsdialog_type_t, CefString const &, CefString const &, CefRefPtr, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnBeforeUnloadJavascriptDialog(CefRefPtr, CefString const &, bool, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnResetJavascriptDialogState(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnJavascriptDialogClosed(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) cefpython_GetDebugOptions(bool *, std::string *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBool(char const *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBoolFromDict(char const *, char const *); +__PYX_EXTERN_C DL_IMPORT(std::string) ApplicationSettings_GetString(char const *); +__PYX_EXTERN_C DL_IMPORT(int) CommandLineSwitches_GetInt(char const *); + +#endif /* !__PYX_HAVE_API__cefpython_py27 */ + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcefpython_py27(void); +#else +PyMODINIT_FUNC PyInit_cefpython_py27(void); +#endif + +#endif /* !__PYX_HAVE__cefpython_py27 */ diff --git a/cefpython/cef3/linux/setup/fix_pyx_files.py b/cefpython/cef3/linux/setup/fix_pyx_files.py new file mode 100644 index 00000000..e25922ba --- /dev/null +++ b/cefpython/cef3/linux/setup/fix_pyx_files.py @@ -0,0 +1,109 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# First, it copies all .pyx files from upper directory to setup/. +# Then, fixes repeating of "include" statements in pyx files. + +# Only the mainfile needs to have "include" statements, +# but we're using PyCharm and to get rid of "unresolved references" +# and other errors displayed in pycharm we are adding "include" +# statements in all of the pyx files. + +# I'm not 100% sure how includes work in Cython, but I suspect that +# a few includes of the same file will include the same content more +# than once, it should work, but function and variable definitions are +# duplicated, it is some kind of overhead and it could lead to some +# problems in the future, better to fix it now. + +# It also checks cdef & cpdef functions whether they are not missing "except *", +# it is required to add it when returning non-python type. + +import glob +import os +import re +import shutil +import sys + +def ExceptAllMissing(content): + + # This is not perfect, won't detect C++ custom types, but will find + # the built-in types, templates and pointers. + patterns = [] + patterns.append( + r"\bcp?def\s+" + "((int|short|long|double|char|unsigned|float|double|cpp_bool" + "|cpp_string|cpp_wstring|uint64_t|uintptr_t|void" + "|CefString)\s+)+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A template ends with bracket: CefRefPtr[CefBrowser] + # or a pointer ends with asterisk: CefBrowser* + "[^\s]+[\]*]\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A reference, eg. CefString& + "[^\s]+&\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + + for pattern in patterns: + match = re.search(pattern, content) + if match: break + + if match: + lineNumber = (content.count("\n", 0, match.start()) + 1) + return lineNumber + +print("\n") +mainfile = "cefpython.pyx" + +pyxfiles = glob.glob("../../../*.pyx") +if not len(pyxfiles): + sys.exit(1) +pyxfiles = [file for file in pyxfiles if file.find(mainfile) == -1] +# Now, pyxfiles contains all pyx files except the mainfile (cefpython.pyx), +# we do not fix includes in mainfile. + +# So that this is the right directory we're in. +if os.path.exists("setup"): + print("Wrong directory, we should be inside setup!") + sys.exit(1) + +# Remove old pyx files in setup directory. +oldpyxfiles = glob.glob("./*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +# Copying pyxfiles and reading its contents. + +print("Copying .pyx files to /setup/: %s" % pyxfiles) +shutil.copy("../../../%s" % mainfile, "./%s" % mainfile) +# Rest of the files will be copied in for loop below. + +print("Fixing includes in .pyx files:") +for pyxfile in pyxfiles: + newfile = "./%s" % os.path.basename(pyxfile) + shutil.copy(pyxfile, newfile) + pyxfile = newfile + with open(pyxfile, "r") as pyxfileopened: + content = pyxfileopened.read() + lineNumber = ExceptAllMissing(content) + if lineNumber: + print("WARNING: 'except *' missing in a cdef/cpdef function, " + "in file %s on line %d" % (os.path.basename(pyxfile), lineNumber)) + sys.exit(1) + # Do not remove the newline - so that line numbers are exact with originals. + (content, subs) = re.subn(r"^include[\t ]+[\"'][^\"'\n\r]+[\"'][\t ]*", "", content, flags=re.MULTILINE) + if subs: + print("%s includes removed in: %s" % (subs, os.path.basename(pyxfile))) + # Reading and writing with the same handle using "r+" mode doesn't work, + # you need to seek(0) and write the same amount of bytes that was in the + # file, otherwise old data from the end of file stays. + with open(pyxfile, "w") as pyxfileopened: + pyxfileopened.write(content) + +print("\n") diff --git a/cefpython/cef3/linux/setup/setup.py b/cefpython/cef3/linux/setup/setup.py new file mode 100755 index 00000000..999e39e2 --- /dev/null +++ b/cefpython/cef3/linux/setup/setup.py @@ -0,0 +1,108 @@ +from distutils.core import setup +# Use "Extension" from Cython.Distutils so that "cython_directives" works. +# from distutils.extension import Extension +from Cython.Distutils import build_ext, Extension +import sys +import platform +from Cython.Compiler import Options +import Cython + +print("Cython version: %s" % Cython.__version__) + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +# Stop on first error, otherwise hundreds of errors appear in the console. +Options.fast_fail = True + +# Written to cython_includes/compile_time_constants.pxi +CEF_VERSION = 3 + +# Python version string: "27" or "32". +PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor) + +def CompileTimeConstants(): + + print("Generating: cython_includes/compile_time_constants.pxi") + with open("./../../../cython_includes/compile_time_constants.pxi", "w") as fd: + fd.write('# This file was generated by setup.py\n') + # A way around Python 3.2 bug: UNAME_SYSNAME is not set. + fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0]) + fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION) + fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major) + +CompileTimeConstants() + +ext_modules = [Extension( + + "cefpython_py%s" % PYTHON_VERSION, + ["cefpython.pyx"], + + # Ignore the warning in the console: + # > C:\Python27\lib\distutils\extension.py:133: UserWarning: + # > Unknown Extension options: 'cython_directives' warnings.warn(msg) + cython_directives={ + # Any conversion to unicode must be explicit using .decode(). + "c_string_type": "bytes", + "c_string_encoding": "utf-8", + }, + + language='c++', + include_dirs=[ + r'./../', + r'./../../', + r'./../../../', + r'./../../../cython_includes/', + '/usr/include/gtk-2.0', + '/usr/include/glib-2.0', + '/usr/include/cairo', + '/usr/include/pango-1.0', + '/usr/include/gdk-pixbuf-2.0', + '/usr/include/atk-1.0', + # Ubuntu + '/usr/lib/x86_64-linux-gnu/glib-2.0/include', + '/usr/lib/x86_64-linux-gnu/gtk-2.0/include', + '/usr/lib/i386-linux-gnu/gtk-2.0/include', + '/usr/lib/i386-linux-gnu/glib-2.0/include', + # Fedora + '/usr/lib64/glib-2.0/include', + '/usr/lib64/gtk-2.0/include', + '/usr/lib/glib-2.0/include', + '/usr/lib/gtk-2.0/include', + ], + + # http_authentication not implemented on Linux. + library_dirs=[ + r'./lib_%s' % BITS, + # r'./../../v8function_handler/', + r'./../../client_handler/', + r'./../../subprocess/', # libcefpythonapp + r'./../../../cpp_utils/' + ], + + libraries=[ + 'cef_dll_wrapper', + # 'v8function_handler', + 'client_handler', + 'cefpythonapp', + 'cpp_utils' + ], + + # Loading libcef.so will only work when running scripts from the same + # directory that libcef.so resides in when you put "./" in here. + # runtime_library_dirs=[ + # './' + #], + + extra_compile_args=[], + extra_link_args=[], + + # Defining macros: + # define_macros = [("UNICODE","1"), ("_UNICODE","1"), ] +)] + +setup( + name = 'cefpython_py%s' % PYTHON_VERSION, + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules +) diff --git a/cefpython/cef3/linux/wxpython.sh b/cefpython/cef3/linux/wxpython.sh new file mode 100755 index 00000000..f28b13c1 --- /dev/null +++ b/cefpython/cef3/linux/wxpython.sh @@ -0,0 +1,2 @@ +cd binaries_64bit +python wxpython.py diff --git a/cefpython/cef3/mac/.gitignore b/cefpython/cef3/mac/.gitignore new file mode 100644 index 00000000..af654df0 --- /dev/null +++ b/cefpython/cef3/mac/.gitignore @@ -0,0 +1,5 @@ +Resources/ +*.dylib +*.so +subprocess +webcache/ diff --git a/cefpython/cef3/mac/binaries_32bit/prism.css b/cefpython/cef3/mac/binaries_32bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/mac/binaries_32bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/mac/binaries_32bit/prism.js b/cefpython/cef3/mac/binaries_32bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/mac/binaries_32bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/mac/binaries_32bit/wxpython.html b/cefpython/cef3/mac/binaries_32bit/wxpython.html new file mode 100644 index 00000000..c23b384f --- /dev/null +++ b/cefpython/cef3/mac/binaries_32bit/wxpython.html @@ -0,0 +1,708 @@ + + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + +Use mouse context menu to go Back/Forward in navigation history.
+ +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
+ +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key (on Mac: Cmd+Opt+I) which is handled in + KeyboardHandler.OnKeyEvent.
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python') +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ +Try this: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu to return back +here after visiting the url:
+ + https://tv.eurosport.com/do-not-allow +
+ +This url will be allowed:
+ + https://tv.eurosport.com/ + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
    + Or visit it in a js popup:
    + + javascript:window.open('http://www.html-kit.com/tools/cookietester/') +
  2. +
  3. Open cookietester in a popup:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie: +external.SetCookie() +
+ +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+ + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +Try this: + + http://www.non-existent.nono/ +

+ +Note: after you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/mac/binaries_32bit/wxpython.py b/cefpython/cef3/mac/binaries_32bit/wxpython.py new file mode 100644 index 00000000..7fa98e27 --- /dev/null +++ b/cefpython/cef3/mac/binaries_32bit/wxpython.py @@ -0,0 +1,855 @@ +# An example of embedding CEF browser in wxPython on Mac. +# Tested with wxPython3.0-osx-3.0.2.0-cocoa-py2.7.dmg which +# was downloaded from the wxpython.org website. + +# IMPORTANT - importing CEF Python +# -------------------------------------------------------------- +# The cefpython library must be the very first library imported. +# This is because CEF was compiled with the tcmalloc memory +# allocator which hooks globally and replaces the default +# malloc allocator. If memory was allocated using malloc and +# then freed using tcmalloc then this would result in random +# segmentation faults in an application. See Issue 155 which +# is to provide CEF builds on Mac with tcmalloc disabled: +# https://code.google.com/p/cefpython/issues/detail?id=155 + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.dylib') +if os.path.exists(libcef_so): + # Import a local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect +import struct + +g_applicationSettings = None +g_browserSettings = None +g_switches = None +g_countWindows = 0 + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + clientHandler = None + javascriptExternal = None + + def __init__(self, url=None): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(800,600)) + + global g_countWindows + g_countWindows += 1 + + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + self.clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + self.clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + self.clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + self.clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + (width, height) = self.mainPanel.GetClientSizeTuple() + windowInfo.SetAsChild(self.mainPanel.GetHandle(), + [0, 0, width, height]) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings=g_browserSettings, + navigateUrl=url) + + self.clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(self.clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + self.javascriptExternal = JavascriptExternal(self.browser) + jsBindings.SetObject("external", self.javascriptExternal) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # Remove all CEF browser references so that browser is closed + # cleanly. Otherwise there may be issues for example with cookies + # not being flushed to disk when closing app immediately + # (Issue 158). + del self.javascriptExternal.mainBrowser + del self.clientHandler.mainBrowser + del self.browser + + # Destroy wx frame, this will complete the destruction of CEF browser + self.Destroy() + + # In wx.chromectrl calling browser.CloseBrowser and/or self.Destroy + # may cause crashes when embedding multiple browsers in tab + # (Issue 107). In such case instead of calling CloseBrowser/Destroy + # try this code: + # | self.browser.ParentWindowWillClose() + # | event.Skip() + + global g_countWindows + g_countWindows -= 1 + if g_countWindows == 0: + # On Win/Linux the call to cefpython.Shutdown() is after + # app.MainLoop() returns, but on Mac it needs to be here. + cefpython.Shutdown() + print("[wxpython.py] OnClose: Exiting") + wx.GetApp().Exit() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def CreateAnotherBrowser(self, url=None): + """ + TODO: There are errors in the console when closing the window: + >> Check failed: window + >> Gdk: _gdk_window_destroy_hierarchy: assertion `GDK_IS_WINDOW\ + >> (window)' failed + >> GLib-GObject: g_object_unref: assertion `G_IS_OBJECT (object)' failed + """ + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.GetMainFrame().ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s"\ + % event["focus_on_editable_field"]) + if platform.system() == "Linux": + # F5 + if event["native_key_code"] == 71: + print("[wxpython.py] F5 pressed, calling"\ + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if event["native_key_code"] == 9: + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if event["native_key_code"] == 96: + print("[wxpython.py] F12 pressed, calling"\ + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + elif platform.system() == "Windows": + # F5 todo + # Escape todo + pass + elif platform.system() == "Darwin": + # Cmd+Opt+I + if event["modifiers"] == 136 and event["character"] == 94: + browser.ShowDevTools() + return True + # F5 + if event["modifiers"] == 0 and event["character"] == 63240: + browser.ReloadIgnoreCache() + return True + # Esc + if event["modifiers"] == 0 and event["character"] == 27: + browser.StopLoad() + return True + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + if "cache_path" in g_applicationSettings: + path = g_applicationSettings["cache_path"] + # path = os.path.join(path, "cookies_browser_{}".format( + # browser.GetIdentifier())) + cookieManager.SetStoragePath(path) + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl.startswith( + "https://tv.eurosport.com/do-not-allow"): + print(" Not allowed!") + return False + if requestUrl.startswith( + "https://tv.eurosport.com/"): + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load"\ + " error: Esc was pressed or file download was aborted") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName,\ + popupFeatures, windowInfo, client, browserSettings,\ + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + allowPopups = True + return not allowPopups + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("[wxpython.py] OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + +if __name__ == '__main__': + print('[wxpython.py] architecture=%s-bit' % (8 * struct.calcsize("P"))) + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + g_applicationSettings = { + # Disk cache + # "cache_path": "webcache/", + + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + + # "resources_dir_path" must be set on Mac, "locales_dir_path" not. + # You must also set "locale_pak" using command line switch. + "resources_dir_path": cefpython.GetModuleDirectory()+"/Resources", + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + "downloads_enabled": True, + + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": False, + } + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + g_switches = { + # On Mac it is required to provide path to a specific + # locale.pak file. On Win/Linux you only specify the + # ApplicationSettings.locales_dir_path option. + "locale_pak": cefpython.GetModuleDirectory() + +"/Resources/en.lproj/locale.pak", + + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "remote-debugging-port": "12345", + # "disable-gpu": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(g_applicationSettings, g_switches) + + app = MyApp(False) + app.MainLoop() + + # Let wx.App destructor do the cleanup before calling + # cefpython.Shutdown(). This is to ensure reliable CEF shutdown. + del app + + # On Mac cefpython.Shutdown() is called in MainFrame.OnClose, + # followed by wx.GetApp.Exit(). diff --git a/cefpython/cef3/mac/binaries_64bit/prism.css b/cefpython/cef3/mac/binaries_64bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/mac/binaries_64bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/mac/binaries_64bit/prism.js b/cefpython/cef3/mac/binaries_64bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/mac/binaries_64bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/mac/binaries_64bit/wxpython.html b/cefpython/cef3/mac/binaries_64bit/wxpython.html new file mode 100644 index 00000000..c23b384f --- /dev/null +++ b/cefpython/cef3/mac/binaries_64bit/wxpython.html @@ -0,0 +1,708 @@ + + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + +Use mouse context menu to go Back/Forward in navigation history.
+ +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
+ +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key (on Mac: Cmd+Opt+I) which is handled in + KeyboardHandler.OnKeyEvent.
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python') +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ +Try this: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu to return back +here after visiting the url:
+ + https://tv.eurosport.com/do-not-allow +
+ +This url will be allowed:
+ + https://tv.eurosport.com/ + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
    + Or visit it in a js popup:
    + + javascript:window.open('http://www.html-kit.com/tools/cookietester/') +
  2. +
  3. Open cookietester in a popup:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie: +external.SetCookie() +
+ +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+ + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +Try this: + + http://www.non-existent.nono/ +

+ +Note: after you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/mac/binaries_64bit/wxpython.py b/cefpython/cef3/mac/binaries_64bit/wxpython.py new file mode 100644 index 00000000..7fa98e27 --- /dev/null +++ b/cefpython/cef3/mac/binaries_64bit/wxpython.py @@ -0,0 +1,855 @@ +# An example of embedding CEF browser in wxPython on Mac. +# Tested with wxPython3.0-osx-3.0.2.0-cocoa-py2.7.dmg which +# was downloaded from the wxpython.org website. + +# IMPORTANT - importing CEF Python +# -------------------------------------------------------------- +# The cefpython library must be the very first library imported. +# This is because CEF was compiled with the tcmalloc memory +# allocator which hooks globally and replaces the default +# malloc allocator. If memory was allocated using malloc and +# then freed using tcmalloc then this would result in random +# segmentation faults in an application. See Issue 155 which +# is to provide CEF builds on Mac with tcmalloc disabled: +# https://code.google.com/p/cefpython/issues/detail?id=155 + +import ctypes, os, sys +libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\ + 'libcef.dylib') +if os.path.exists(libcef_so): + # Import a local module + ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + if 0x02070000 <= sys.hexversion < 0x03000000: + import cefpython_py27 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect +import struct + +g_applicationSettings = None +g_browserSettings = None +g_switches = None +g_countWindows = 0 + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority (default) +# EVT_TIMER - cef browser has priority +# It seems that Flash content behaves better when using a timer. +# IMPORTANT! On Linux EVT_IDLE does not work, the events seems to +# be propagated only when you move your mouse, which is not the +# expected behavior, it is recommended to use EVT_TIMER on Linux, +# so set this value to False. +USE_EVT_IDLE = False + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + clientHandler = None + javascriptExternal = None + + def __init__(self, url=None): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='wxPython CEF 3 example', size=(800,600)) + + global g_countWindows + g_countWindows += 1 + + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + # Cannot attach browser to the main frame as this will cause + # the menu not to work. + # -- + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + self.clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + self.clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + self.clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + self.clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + (width, height) = self.mainPanel.GetClientSizeTuple() + windowInfo.SetAsChild(self.mainPanel.GetHandle(), + [0, 0, width, height]) + # Linux requires adding "file://" for local files, + # otherwise /home/some will be replaced as http://home/some + self.browser = cefpython.CreateBrowserSync( + windowInfo, + # If there are problems with Flash you can disable it here, + # by disabling all plugins. + browserSettings=g_browserSettings, + navigateUrl=url) + + self.clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(self.clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + self.javascriptExternal = JavascriptExternal(self.browser) + jsBindings.SetObject("external", self.javascriptExternal) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE: + # Bind EVT_IDLE only for the main application frame. + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnClose(self, event): + # Remove all CEF browser references so that browser is closed + # cleanly. Otherwise there may be issues for example with cookies + # not being flushed to disk when closing app immediately + # (Issue 158). + del self.javascriptExternal.mainBrowser + del self.clientHandler.mainBrowser + del self.browser + + # Destroy wx frame, this will complete the destruction of CEF browser + self.Destroy() + + # In wx.chromectrl calling browser.CloseBrowser and/or self.Destroy + # may cause crashes when embedding multiple browsers in tab + # (Issue 107). In such case instead of calling CloseBrowser/Destroy + # try this code: + # | self.browser.ParentWindowWillClose() + # | event.Skip() + + global g_countWindows + g_countWindows -= 1 + if g_countWindows == 0: + # On Win/Linux the call to cefpython.Shutdown() is after + # app.MainLoop() returns, but on Mac it needs to be here. + cefpython.Shutdown() + print("[wxpython.py] OnClose: Exiting") + wx.GetApp().Exit() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def CreateAnotherBrowser(self, url=None): + """ + TODO: There are errors in the console when closing the window: + >> Check failed: window + >> Gdk: _gdk_window_destroy_hierarchy: assertion `GDK_IS_WINDOW\ + >> (window)' failed + >> GLib-GObject: g_object_unref: assertion `G_IS_OBJECT (object)' failed + """ + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.GetMainFrame().ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s"\ + % event["focus_on_editable_field"]) + if platform.system() == "Linux": + # F5 + if event["native_key_code"] == 71: + print("[wxpython.py] F5 pressed, calling"\ + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if event["native_key_code"] == 9: + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if event["native_key_code"] == 96: + print("[wxpython.py] F12 pressed, calling"\ + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + elif platform.system() == "Windows": + # F5 todo + # Escape todo + pass + elif platform.system() == "Darwin": + # Cmd+Opt+I + if event["modifiers"] == 136 and event["character"] == 94: + browser.ShowDevTools() + return True + # F5 + if event["modifiers"] == 0 and event["character"] == 63240: + browser.ReloadIgnoreCache() + return True + # Esc + if event["modifiers"] == 0 and event["character"] == 27: + browser.StopLoad() + return True + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + if "cache_path" in g_applicationSettings: + path = g_applicationSettings["cache_path"] + # path = os.path.join(path, "cookies_browser_{}".format( + # browser.GetIdentifier())) + cookieManager.SetStoragePath(path) + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl.startswith( + "https://tv.eurosport.com/do-not-allow"): + print(" Not allowed!") + return False + if requestUrl.startswith( + "https://tv.eurosport.com/"): + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load"\ + " error: Esc was pressed or file download was aborted") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName,\ + popupFeatures, windowInfo, client, browserSettings,\ + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + allowPopups = True + return not allowPopups + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + timerCount = 0 + + def OnInit(self): + if not USE_EVT_IDLE: + self.CreateTimer() + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + self.timerCount += 1 + # print("[wxpython.py] OnTimer() %d" % self.timerCount) + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + if not USE_EVT_IDLE: + self.timer.Stop() + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + +if __name__ == '__main__': + print('[wxpython.py] architecture=%s-bit' % (8 * struct.calcsize("P"))) + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + g_applicationSettings = { + # Disk cache + # "cache_path": "webcache/", + + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + + # "resources_dir_path" must be set on Mac, "locales_dir_path" not. + # You must also set "locale_pak" using command line switch. + "resources_dir_path": cefpython.GetModuleDirectory()+"/Resources", + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + "downloads_enabled": True, + + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": False, + } + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + g_switches = { + # On Mac it is required to provide path to a specific + # locale.pak file. On Win/Linux you only specify the + # ApplicationSettings.locales_dir_path option. + "locale_pak": cefpython.GetModuleDirectory() + +"/Resources/en.lproj/locale.pak", + + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "remote-debugging-port": "12345", + # "disable-gpu": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(g_applicationSettings, g_switches) + + app = MyApp(False) + app.MainLoop() + + # Let wx.App destructor do the cleanup before calling + # cefpython.Shutdown(). This is to ensure reliable CEF shutdown. + del app + + # On Mac cefpython.Shutdown() is called in MainFrame.OnClose, + # followed by wx.GetApp.Exit(). diff --git a/cefpython/cef3/mac/compile.py b/cefpython/cef3/mac/compile.py new file mode 100644 index 00000000..30848f8f --- /dev/null +++ b/cefpython/cef3/mac/compile.py @@ -0,0 +1,181 @@ +import sys +import os +import glob +import shutil +import subprocess +import platform +import stat +import re + +# This will not show "Segmentation fault" error message: +# | subprocess.call(["python", "./wxpython.py"]) +# You need to call it with shell=True for this kind of +# error message to be shown: +# | subprocess.call("python wxpython.py", shell=True) + +# How to debug: +# 1. Install "python-dbg" package +# 2. Install "python-wxgtk2.8-dbg" package +# 3. Run "python compile.py debug" +# 4. In cygdb type "cy run" +# 5. To display debug backtrace type "cy bt" +# 6. More commands: http://docs.cython.org/src/userguide/debugging.html + +if len(sys.argv) > 1 and "--debug" in sys.argv: + DEBUG = True + print("DEBUG mode On") +else: + DEBUG = False + +if len(sys.argv) > 1 and re.search(r"^\d+\.\d+$", sys.argv[1]): + VERSION = sys.argv[1] +else: + print("[compile.py] ERROR: expected first argument to be version number") + print(" Allowed version format: \\d+\.\\d+") + sys.exit(1) + +print("VERSION=%s"%VERSION) + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") +PYTHON_CMD = "python" +if sys.maxint == 2147483647: + BITS = "32bit" + PYTHON_CMD = "arch -i386 python" + +if BITS == "32bit": + if "i386" not in os.getenv("ARCHFLAGS", ""): + raise Exception("Detected Python 32bit, but ARCHFLAGS is not i386") + if "i386" not in os.getenv("CEF_CCFLAGS", ""): + raise Exception("Detected Python 32bit, but CEF_CCFLAGS is not i386") +elif BITS == "64bit": + if "x86_64" not in os.getenv("ARCHFLAGS", ""): + raise Exception("Detected Python 64bit, but ARCHFLAGS is not x86_64") + if "x86_64" not in os.getenv("CEF_CCFLAGS", ""): + raise Exception("Detected Python 64bit, but CEF_CCFLAGS is not x86_64") + +PYVERSION = str(sys.version_info[0])+str(sys.version_info[1]) +print("PYVERSION = %s" % PYVERSION) +print("BITS = %s" % BITS) + +os.environ["CC"] = "gcc" +os.environ["CXX"] = "g++" + +print("Compiling C++ projects") + +# Need to allow continuing even when make fails, as it may +# fail because the "public" function declaration is not yet +# in "cefpython.h", but for it to be generated we need to run +# cython compiling, so in this case you continue even when make +# fails and then run the compile.py script again and this time +# make should succeed. + +os.chdir("./../../cpp_utils/") +subprocess.call("rm -f *.o *.a", shell=True) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +os.chdir("./../cef3/client_handler/") +subprocess.call("rm -f *.o *.a", shell=True) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +os.chdir("./../subprocess/") +subprocess.call("rm -f *.o *.a", shell=True) +subprocess.call("rm -f subprocess", shell=True) + +ret = subprocess.call("make -f Makefile-libcefpythonapp", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) + +ret = subprocess.call("make -f Makefile", shell=True) +if ret != 0: + what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") + if what != "y": + sys.exit(1) +subprocess_exe = "./../mac/binaries_%s/subprocess" % (BITS) +if os.path.exists("./subprocess"): + # .copy() will also copy Permission bits + shutil.copy("./subprocess", subprocess_exe) + +# os.chdir("./../v8function_handler/") +# ret = subprocess.call("make -f Makefile", shell=True) +# if ret != 0: +# what = raw_input("make failed, press 'y' to continue, 'n' to stop: ") +# if what != "y": +# sys.exit(1) + +os.chdir("./../mac/") + +try: + os.remove("./binaries_%s/cefpython_py%s.so" % (BITS, PYVERSION)) +except OSError: + pass + +os.system("rm ./setup/cefpython_py*.so") + +pyx_files = glob.glob("./setup/*.pyx") +for f in pyx_files: + os.remove(f) + +try: + shutil.rmtree("./setup/build") +except OSError: + pass + +os.chdir("./setup") + +ret = subprocess.call(PYTHON_CMD+" fix_pyx_files.py", shell=True) +if ret != 0: + sys.exit("ERROR") + +# Create __version__.pyx after fix_pyx_files.py was called, +# as that script deletes old pyx files before copying new ones. +print("Creating __version__.pyx file") +with open("__version__.pyx", "w") as fo: + fo.write('__version__ = "{}"\n'.format(VERSION)) + +if DEBUG: + ret = subprocess.call(PYTHON_CMD+"-dbg setup.py build_ext --inplace" + " --cython-gdb", shell=True) +else: + ret = subprocess.call(PYTHON_CMD+" setup.py build_ext --inplace", shell=True) + +if DEBUG: + shutil.rmtree("./../binaries_%s/cython_debug/" % BITS, ignore_errors=True) + shutil.copytree("./cython_debug/", "./../binaries_%s/cython_debug/" % BITS) + +os.chdir("../") + +oldpyxfiles = glob.glob("./setup/*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +if ret != 0: + sys.exit("ERROR") + +exitcode = os.system("mv ./setup/cefpython_py{0}*.so" + " ./binaries_{1}/cefpython_py{0}.so" + .format(PYVERSION, BITS)) +if exitcode: + raise RuntimeError("Failed to move the cefpython module") + +print("DONE") + +os.chdir("./binaries_%s" % BITS) +if DEBUG: + subprocess.call("cygdb . --args python-dbg wxpython.py", shell=True) +else: + subprocess.call(PYTHON_CMD+" wxpython.py", shell=True) diff --git a/cefpython/cef3/mac/installer/.gitignore b/cefpython/cef3/mac/installer/.gitignore new file mode 100644 index 00000000..a0d54479 --- /dev/null +++ b/cefpython/cef3/mac/installer/.gitignore @@ -0,0 +1,3 @@ +/cefpython3-*/ +dist/ +binaries_fat/ diff --git a/cefpython/cef3/mac/installer/__init__.py.template b/cefpython/cef3/mac/installer/__init__.py.template new file mode 100644 index 00000000..e3620471 --- /dev/null +++ b/cefpython/cef3/mac/installer/__init__.py.template @@ -0,0 +1,28 @@ +__all__ = ["cefpython", "wx"] +__version__ = "%(APP_VERSION)s" +__author__ = "The CEF Python authors" + +import os +import ctypes + +package_dir = os.path.dirname(os.path.abspath(__file__)) + +# On Mac it works without setting library paths, but let's set it +# just to be sure. +os.environ["LD_LIBRARY_PATH"] = package_dir +os.environ["DYLD_LIBRARY_PATH"] = package_dir + +# This env variable will be returned by cefpython.GetModuleDirectory(). +os.environ["CEFPYTHON3_PATH"] = package_dir + +# This loads the libcef.so library for the main python executable. +# The libffmpegsumo.so library shouldn't be loaded here, it could +# cause issues to load it in the browser process. +libcef_so = os.path.join(package_dir, "libcef.dylib") +ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL) + +import sys +if 0x02070000 <= sys.hexversion < 0x03000000: + from . import cefpython_py27 as cefpython +else: + raise Exception("Unsupported python version: " + sys.version) diff --git a/cefpython/cef3/mac/installer/build_all.sh b/cefpython/cef3/mac/installer/build_all.sh new file mode 100755 index 00000000..fcf2821f --- /dev/null +++ b/cefpython/cef3/mac/installer/build_all.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "ERROR: Provide an argument: version number eg. 31.2" + exit 1 +fi + +echo "Removing old directories" +rm -rf cefpython3-*-setup/ +rm -rf dist/ + +echo "Running make-setup.py" +python make-setup.py -v $1 +if [ $? -ne 0 ]; then echo "ERROR: make-setup.py" && exit 1; fi; + +setup_dirs=(cefpython3-*-setup) +setup_dir=${setup_dirs[0]} + +echo "Packing setup directory to .tar.gz" +tar -zcvf $setup_dir.tar.gz $setup_dir/ +if [ $? -ne 0 ]; then echo "ERROR: tar -zcvf $setup_dir..." && exit 1; fi; + +echo "Moving setup.tar.gz to dist/" +mkdir dist/ +mv $setup_dir.tar.gz dist/ +if [ $? -ne 0 ]; then echo "ERROR: mv $setup_dir..." && exit 1; fi; + +echo "Installing the wheel package" +pip install wheel +if [ $? -ne 0 ]; then echo "ERROR: pip install wheel" && exit 1; fi; + +echo "Creating a Python Wheel package" +cd $setup_dir +python setup.py bdist_wheel +if [ $? -ne 0 ]; then echo "ERROR: python setup.py bdist_wheel" && exit 1; fi; + +echo "Moving .whl package to dist/" +mv dist/*.whl ../dist/ +if [ $? -ne 0 ]; then echo "ERROR: mv dist/*.whl..." && exit 1; fi; + +cd ../ + +cd dist/ +echo "Files in the dist/ directory:" +ls -l + +echo "DONE" diff --git a/cefpython/cef3/mac/installer/build_run_chromectrl.sh b/cefpython/cef3/mac/installer/build_run_chromectrl.sh new file mode 100755 index 00000000..828b3075 --- /dev/null +++ b/cefpython/cef3/mac/installer/build_run_chromectrl.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Stop on first error: +# set -e + +bash ./build_all.sh 99.99 + +if [ ! -d "dist/" ]; then echo "ERROR: dist/ does not exist" && exit 1; fi; +cd dist/ + +cwd=$(pwd) +yes | pip uninstall cefpython3 + +pip install --upgrade cefpython3 --no-index --find-links=file://$cwd +if [ $? -ne 0 ]; then echo "ERROR: pip install cefpython3..." && exit 1; fi; +cd ../ + +cd ../../wx-subpackage/examples/ + +python sample1.py +#if [ $? -ne 0 ]; then echo "ERROR: python sample1.py" && exit 1; fi; + +python sample2.py +#if [ $? -ne 0 ]; then echo "ERROR: python sample2.py" && exit 1; fi; + +python sample3.py +#if [ $? -ne 0 ]; then echo "ERROR: python sample3.py" && exit 1; fi; + +cd ../../mac/installer/ + +yes | pip uninstall cefpython3 diff --git a/cefpython/cef3/mac/installer/make-setup.py b/cefpython/cef3/mac/installer/make-setup.py new file mode 100644 index 00000000..70bb16b0 --- /dev/null +++ b/cefpython/cef3/mac/installer/make-setup.py @@ -0,0 +1,172 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a setup package. + +import sys +import os +import platform +import argparse +import re +import shutil +import glob +import sysconfig +import subprocess +import struct + +BITS = "%sbit" % (8 * struct.calcsize("P")) + +PACKAGE_NAME = "cefpython3" + +INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template" +SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template" +PY_VERSION_DIGITS_ONLY = (str(sys.version_info.major) + "" + + str(sys.version_info.minor)) # "27" or "34" + +def str_format(string, dictionary): + orig_string = string + for key, value in dictionary.iteritems(): + string = string.replace("%("+key+")s", value) + if string == orig_string: + raise Exception("Nothing to format") + if re.search(r"%\([a-zA-Z0-9_]+\)s", string): + raise Exception("Not all strings formatted") + return string + +def get_binaries_dir(b32, b64, bfat): + pyver = PY_VERSION_DIGITS_ONLY + if (os.path.exists(b32 + "/cefpython_py{}.so".format(pyver)) + and os.path.exists(b64 + "/cefpython_py{}.so".format(pyver))): + create_fat_binaries(b32, b64, bfat) + return bfat + return os.path.abspath(installer_dir+"/../binaries_"+BITS+"/") + +def create_fat_binaries(b32, b64, bfat): + print("Creating fat binaries") + if os.path.exists(bfat): + shutil.rmtree(bfat) + os.mkdir(bfat) + res = os.system("cp -rf {}/* {}/".format(b64, bfat)) + assert res == 0 + files = os.listdir(b32) + for fbase in files: + if not (fbase.endswith(".dylib") or fbase.endswith(".so") + or fbase.endswith("subprocess")): + continue + fname32 = os.path.join(b32, fbase) + fname64 = os.path.join(b64, fbase) + fnamefat = os.path.join(bfat, fbase) + print("Creating fat binary: {}".format(fbase)) + res = os.system("lipo {} {} -create -output {}" + .format(fname32, fname64, fnamefat)) + assert res == 0 + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + vars = {} + vars["APP_VERSION"] = args.version + # vars["PLATFORM"] = sysconfig.get_platform() + vars["PLATFORM"] = "macosx" + vars["PY_VERSION_DIGITS_ONLY"] = PY_VERSION_DIGITS_ONLY + + print("Reading template: %s" % INIT_TEMPLATE) + f = open(INIT_TEMPLATE) + INIT_CONTENT = str_format(f.read(), vars) + f.close() + + print("Reading template: %s" % SETUP_TEMPLATE) + f = open(SETUP_TEMPLATE) + SETUP_CONTENT = str_format(f.read(), vars) + f.close() + + installer_dir = os.path.dirname(os.path.abspath(__file__)) + + setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]+"-"+vars["PLATFORM"]+"-setup" + print("Creating setup dir: "+setup_dir) + os.mkdir(setup_dir) + + package_dir = setup_dir+"/"+PACKAGE_NAME + print("Creating package dir") + os.mkdir(package_dir) + + print("Creating setup.py from template") + with open(setup_dir+"/setup.py", "w") as f: + f.write(SETUP_CONTENT) + + # Create fat binaries if both 32bit and 64bit are available + b32 = os.path.abspath(installer_dir+"/../binaries_32bit/") + b64 = os.path.abspath(installer_dir+"/../binaries_64bit/") + bfat = os.path.abspath(installer_dir+"/binaries_fat/") + binaries_dir = get_binaries_dir(b32, b64, bfat) + print("Copying binaries to package dir") + ret = os.system("cp -rf "+binaries_dir+"/* "+package_dir) + assert ret == 0 + + os.chdir(package_dir) + print("Removing .log files from the package dir") + ret = os.system("rm *.log") + # assert ret == 0 - if there are no .log files this assert would fail. + os.chdir(installer_dir) + + print("Creating __init__.py from template") + with open(package_dir+"/__init__.py", "w") as f: + f.write(INIT_CONTENT) + + print("Creating examples dir in package dir") + os.mkdir(package_dir+"/examples/") + + print("Creating wx dir in package dir") + os.mkdir(package_dir+"/wx/") + + print("Moving example scripts from package dir to examples dir") + examples = glob.glob(package_dir+"/*.py") + for example in examples: + # Ignore: cefpython_py27.py - dummy API script + if os.path.basename(example).startswith("cefpython_"): + continue + # Ignore: __init__.py + if os.path.basename(example).startswith("__"): + continue + os.rename(example, package_dir+"/examples/"+os.path.basename(example)) + ret = os.system("mv "+package_dir+"/*.html "+package_dir+"/examples/") + ret = os.system("mv "+package_dir+"/*.js "+package_dir+"/examples/") + ret = os.system("mv "+package_dir+"/*.css "+package_dir+"/examples/") + assert ret == 0 + + print("Copying wx-subpackage to wx dir in package dir") + wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx-subpackage/") + ret = os.system("cp -rf "+wx_subpackage_dir+"/* "+package_dir+"/wx/") + assert ret == 0 + + print("Moving wx examples from wx/examples to examples/wx") + shutil.move(package_dir+"/wx/examples", package_dir+"/wx/wx/") + shutil.move(package_dir+"/wx/wx/", package_dir+"/examples/") + + print("Copying package dir examples to setup dir") + ret = os.system("cp -rf "+package_dir+"/examples/ "+setup_dir+"/examples/") + assert ret == 0 + + # Create empty debug.log files so that package uninstalls cleanly + # in case examples were launched. Issue 149. + debug_log_dirs = [package_dir, + package_dir+"/examples/", + package_dir+"/examples/wx/"] + for dir in debug_log_dirs: + print("Creating empty debug.log in %s" % dir) + with open(dir+"/debug.log", "w") as f: + f.write("") + # Set write permissions so that Wheel package files have it + # right. So that examples may be run from package directory. + subprocess.call("chmod 666 %s/debug.log" % dir, shell=True) + + print("Setup Package created successfully.") + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/mac/installer/setup.py.template b/cefpython/cef3/mac/installer/setup.py.template new file mode 100644 index 00000000..f21d8048 --- /dev/null +++ b/cefpython/cef3/mac/installer/setup.py.template @@ -0,0 +1,79 @@ +from setuptools import setup +from setuptools.command.install import install as _install +from setuptools.dist import Distribution + +try: + # Wheel platform tag gets complicated on Mac, see: + # http://lepture.com/en/2014/python-on-a-hard-wheel + from wheel.bdist_wheel import bdist_wheel + class _bdist_wheel(bdist_wheel): + def get_tag(self): + tag = bdist_wheel.get_tag(self) + platform = ("macosx_10_6_intel" + ".macosx_10_9_intel.macosx_10_9_x86_64" + ".macosx_10_10_intel.macosx_10_10_x86_64") + tag = (tag[0], tag[1], platform) + return tag + cmdclass = {"bdist_wheel": _bdist_wheel} +except ImportError: + cmdclass = {} + +import sys +import os +import subprocess + +class BinaryDistribution(Distribution): + def is_pure(self): + return False + +def get_package_data(directory, base_dir=""): + """ Lists directory recursively. Includes only files. Empty + directories are not included. File paths include the directory + path passed to this function. """ + if base_dir: + old_dir = os.getcwd() + os.chdir(base_dir) + files = os.listdir(directory) + ret = [] + for f in files: + f = os.path.join(directory, f) + if os.path.isdir(f): + ret = ret + get_package_data(f) + else: + ret.append(f) + if base_dir: + os.chdir(old_dir) + return ret + +setup( + distclass=BinaryDistribution, + cmdclass=cmdclass, + name='cefpython3', # No spaces here, so that it works with deb packages. + version='%(APP_VERSION)s', + description='Python bindings for the Chromium Embedded Framework', + license='BSD 3-Clause', + author='Czarek Tomczak', + author_email='czarek.tomczak@gmail.com', + url='http://code.google.com/p/cefpython/', + platforms=['%(PLATFORM)s'], + packages=['cefpython3', 'cefpython3.wx'], + package_data={'cefpython3': [ + 'examples/*.py', + 'examples/*.html', + 'examples/*.js', + 'examples/*.css', + 'examples/wx/*.py', + 'examples/wx/*.html', + 'examples/wx/*.png', + 'wx/*.txt', + 'wx/images/*.png', + '*.txt', + 'subprocess', + '*.so', + '*.dylib', + 'debug.log', + 'examples/debug.log', + 'examples/wx/debug.log',] + + get_package_data("Resources/", "cefpython3/") + } +) diff --git a/cefpython/cef3/mac/mac32.sh b/cefpython/cef3/mac/mac32.sh new file mode 100755 index 00000000..4d8b1709 --- /dev/null +++ b/cefpython/cef3/mac/mac32.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +PATH=/usr/local/bin:$PATH +export PATH +alias python="arch -i386 python" + +CEF_CCFLAGS="-arch i386" +export CEF_CCFLAGS + +ARCHFLAGS="-arch i386" +export ARCHFLAGS + +export CC=gcc +export CXX=g++ diff --git a/cefpython/cef3/mac/mac64.sh b/cefpython/cef3/mac/mac64.sh new file mode 100755 index 00000000..e016d673 --- /dev/null +++ b/cefpython/cef3/mac/mac64.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +PATH=/usr/local/bin:$PATH +export PATH + +CEF_CCFLAGS="-arch x86_64" +export CEF_CCFLAGS + +ARCHFLAGS="-arch x86_64" +export ARCHFLAGS + +export CC=gcc +export CXX=g++ diff --git a/cefpython/cef3/mac/setup/.gitignore b/cefpython/cef3/mac/setup/.gitignore new file mode 100644 index 00000000..67f1cf10 --- /dev/null +++ b/cefpython/cef3/mac/setup/.gitignore @@ -0,0 +1,6 @@ +build/ +cefpython.cpp +cython_debug/ +*.pyx +*.cpp +*.a diff --git a/cefpython/cef3/mac/setup/cefpython.h b/cefpython/cef3/mac/setup/cefpython.h new file mode 100644 index 00000000..1eb60603 --- /dev/null +++ b/cefpython/cef3/mac/setup/cefpython.h @@ -0,0 +1,93 @@ +#ifndef __PYX_HAVE__cefpython_py27 +#define __PYX_HAVE__cefpython_py27 + + +#ifndef __PYX_HAVE_API__cefpython_py27 + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +__PYX_EXTERN_C DL_IMPORT(void) PyBrowser_ShowDevTools(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) PyTaskRunnable(int); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(int, int64); +__PYX_EXTERN_C DL_IMPORT(void) V8FunctionHandler_Execute(CefRefPtr, CefRefPtr, CefString &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RemovePythonCallbacksForFrame(int); +__PYX_EXTERN_C DL_IMPORT(bool) ExecutePythonCallback(CefRefPtr, int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_OnBeforePopup(CefRefPtr, CefRefPtr, CefString const &, CefString const &, int const , CefWindowInfo &, CefRefPtr &, CefBrowserSettings &, bool *); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnAfterCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_RunModal(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_DoClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr, CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnTooltip(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnStatusMessage(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnConsoleMessage(CefRefPtr, CefString const &, CefString const &, int); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnPreKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle, bool *); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeResourceLoad(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeBrowse(CefRefPtr, CefRefPtr, CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetResourceHandler(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceRedirect(CefRefPtr, CefRefPtr, CefString const &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr, CefRefPtr, bool, CefString const &, int, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnQuotaRequest(CefRefPtr, CefString const &, int64, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetCookieManager(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnProtocolExecution(CefRefPtr, CefString const &, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforePluginLoad(CefRefPtr, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnCertificateError(int, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnRendererProcessTerminated(CefRefPtr, enum cef_termination_status_t); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnPluginCrashed(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) CookieVisitor_Visit(int, CefCookie const &, int, int, bool &); +__PYX_EXTERN_C DL_IMPORT(void) StringVisitor_Visit(int, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadingStateChange(CefRefPtr, bool, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadStart(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadEnd(CefRefPtr, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadError(CefRefPtr, CefRefPtr, enum cef_errorcode_t, CefString const &, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnRenderProcessThreadCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnBeforeChildProcessLaunch(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetRootScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetViewRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenPoint(CefRefPtr, int, int, int &, int &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenInfo(CefRefPtr, CefScreenInfo &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupShow(CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupSize(CefRefPtr, CefRect const &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPaint(CefRefPtr, cef_paint_element_type_t, std::vector &, void const *, int, int); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnCursorChange(CefRefPtr, CefCursorHandle); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnScrollOffsetChanged(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ProcessRequest(int, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_GetResponseHeaders(int, CefRefPtr, int64 &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ReadResponse(int, void *, int, int &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanGetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanSetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_Cancel(int); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnUploadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadData(int, CefRefPtr, void const *, size_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnRequestComplete(int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) App_OnBeforeCommandLineProcessing_BrowserProcess(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnJavascriptDialog(CefRefPtr, CefString const &, CefString const &, enum cef_jsdialog_type_t, CefString const &, CefString const &, CefRefPtr, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnBeforeUnloadJavascriptDialog(CefRefPtr, CefString const &, bool, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnResetJavascriptDialogState(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnJavascriptDialogClosed(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) cefpython_GetDebugOptions(bool *, std::string *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBool(char const *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBoolFromDict(char const *, char const *); +__PYX_EXTERN_C DL_IMPORT(std::string) ApplicationSettings_GetString(char const *); +__PYX_EXTERN_C DL_IMPORT(int) CommandLineSwitches_GetInt(char const *); + +#endif /* !__PYX_HAVE_API__cefpython_py27 */ + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcefpython_py27(void); +#else +PyMODINIT_FUNC PyInit_cefpython_py27(void); +#endif + +#endif /* !__PYX_HAVE__cefpython_py27 */ diff --git a/cefpython/cef3/mac/setup/fix_pyx_files.py b/cefpython/cef3/mac/setup/fix_pyx_files.py new file mode 100644 index 00000000..e25922ba --- /dev/null +++ b/cefpython/cef3/mac/setup/fix_pyx_files.py @@ -0,0 +1,109 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# First, it copies all .pyx files from upper directory to setup/. +# Then, fixes repeating of "include" statements in pyx files. + +# Only the mainfile needs to have "include" statements, +# but we're using PyCharm and to get rid of "unresolved references" +# and other errors displayed in pycharm we are adding "include" +# statements in all of the pyx files. + +# I'm not 100% sure how includes work in Cython, but I suspect that +# a few includes of the same file will include the same content more +# than once, it should work, but function and variable definitions are +# duplicated, it is some kind of overhead and it could lead to some +# problems in the future, better to fix it now. + +# It also checks cdef & cpdef functions whether they are not missing "except *", +# it is required to add it when returning non-python type. + +import glob +import os +import re +import shutil +import sys + +def ExceptAllMissing(content): + + # This is not perfect, won't detect C++ custom types, but will find + # the built-in types, templates and pointers. + patterns = [] + patterns.append( + r"\bcp?def\s+" + "((int|short|long|double|char|unsigned|float|double|cpp_bool" + "|cpp_string|cpp_wstring|uint64_t|uintptr_t|void" + "|CefString)\s+)+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A template ends with bracket: CefRefPtr[CefBrowser] + # or a pointer ends with asterisk: CefBrowser* + "[^\s]+[\]*]\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A reference, eg. CefString& + "[^\s]+&\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + + for pattern in patterns: + match = re.search(pattern, content) + if match: break + + if match: + lineNumber = (content.count("\n", 0, match.start()) + 1) + return lineNumber + +print("\n") +mainfile = "cefpython.pyx" + +pyxfiles = glob.glob("../../../*.pyx") +if not len(pyxfiles): + sys.exit(1) +pyxfiles = [file for file in pyxfiles if file.find(mainfile) == -1] +# Now, pyxfiles contains all pyx files except the mainfile (cefpython.pyx), +# we do not fix includes in mainfile. + +# So that this is the right directory we're in. +if os.path.exists("setup"): + print("Wrong directory, we should be inside setup!") + sys.exit(1) + +# Remove old pyx files in setup directory. +oldpyxfiles = glob.glob("./*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +# Copying pyxfiles and reading its contents. + +print("Copying .pyx files to /setup/: %s" % pyxfiles) +shutil.copy("../../../%s" % mainfile, "./%s" % mainfile) +# Rest of the files will be copied in for loop below. + +print("Fixing includes in .pyx files:") +for pyxfile in pyxfiles: + newfile = "./%s" % os.path.basename(pyxfile) + shutil.copy(pyxfile, newfile) + pyxfile = newfile + with open(pyxfile, "r") as pyxfileopened: + content = pyxfileopened.read() + lineNumber = ExceptAllMissing(content) + if lineNumber: + print("WARNING: 'except *' missing in a cdef/cpdef function, " + "in file %s on line %d" % (os.path.basename(pyxfile), lineNumber)) + sys.exit(1) + # Do not remove the newline - so that line numbers are exact with originals. + (content, subs) = re.subn(r"^include[\t ]+[\"'][^\"'\n\r]+[\"'][\t ]*", "", content, flags=re.MULTILINE) + if subs: + print("%s includes removed in: %s" % (subs, os.path.basename(pyxfile))) + # Reading and writing with the same handle using "r+" mode doesn't work, + # you need to seek(0) and write the same amount of bytes that was in the + # file, otherwise old data from the end of file stays. + with open(pyxfile, "w") as pyxfileopened: + pyxfileopened.write(content) + +print("\n") diff --git a/cefpython/cef3/mac/setup/lib_32bit/README b/cefpython/cef3/mac/setup/lib_32bit/README new file mode 100644 index 00000000..623f0324 --- /dev/null +++ b/cefpython/cef3/mac/setup/lib_32bit/README @@ -0,0 +1 @@ +Put libcef_dll_wrapper.a here diff --git a/cefpython/cef3/mac/setup/lib_64bit/README b/cefpython/cef3/mac/setup/lib_64bit/README new file mode 100644 index 00000000..623f0324 --- /dev/null +++ b/cefpython/cef3/mac/setup/lib_64bit/README @@ -0,0 +1 @@ +Put libcef_dll_wrapper.a here diff --git a/cefpython/cef3/mac/setup/setup.py b/cefpython/cef3/mac/setup/setup.py new file mode 100755 index 00000000..4a2b2e01 --- /dev/null +++ b/cefpython/cef3/mac/setup/setup.py @@ -0,0 +1,115 @@ +from distutils.core import setup +# Use "Extension" from Cython.Distutils so that "cython_directives" works. +# from distutils.extension import Extension +from Cython.Distutils import build_ext, Extension +import sys +import os +import platform +from Cython.Compiler import Options +import Cython + +print("Cython version: %s" % Cython.__version__) + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") +if sys.maxint == 2147483647: + BITS = "32bit" + +print("BITS=%s" % BITS) + +os.environ["CC"] = "gcc" +os.environ["CXX"] = "g++" + +# Stop on first error, otherwise hundreds of errors appear in the console. +Options.fast_fail = True + +# Written to cython_includes/compile_time_constants.pxi +CEF_VERSION = 3 + +# Python version string: "27" or "32". +PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor) + +def CompileTimeConstants(): + + print("Generating: cython_includes/compile_time_constants.pxi") + with open("./../../../cython_includes/compile_time_constants.pxi", "w") as fd: + fd.write('# This file was generated by setup.py\n') + # A way around Python 3.2 bug: UNAME_SYSNAME is not set. + fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0]) + fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION) + fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major) + +CompileTimeConstants() + +ext_modules = [Extension( + + "cefpython_py%s" % PYTHON_VERSION, + ["cefpython.pyx"], + + # Ignore the warning in the console: + # > C:\Python27\lib\distutils\extension.py:133: UserWarning: + # > Unknown Extension options: 'cython_directives' warnings.warn(msg) + cython_directives={ + # Any conversion to unicode must be explicit using .decode(). + "c_string_type": "bytes", + "c_string_encoding": "utf-8", + }, + + language='c++', + include_dirs=[ + r'./../', + r'./../../', + r'./../../../', + r'./../../../cython_includes/', + '/usr/include/gtk-2.0', + '/usr/include/glib-2.0', + '/usr/include/cairo', + '/usr/include/pango-1.0', + '/usr/include/gdk-pixbuf-2.0', + '/usr/include/atk-1.0', + # Ubuntu + '/usr/lib/x86_64-linux-gnu/glib-2.0/include', + '/usr/lib/x86_64-linux-gnu/gtk-2.0/include', + '/usr/lib/i386-linux-gnu/gtk-2.0/include', + '/usr/lib/i386-linux-gnu/glib-2.0/include', + # Fedora + '/usr/lib64/glib-2.0/include', + '/usr/lib64/gtk-2.0/include', + '/usr/lib/glib-2.0/include', + '/usr/lib/gtk-2.0/include', + ], + + # http_authentication not implemented on Linux. + library_dirs=[ + r'./lib_%s' % BITS, + # r'./../../v8function_handler/', + r'./../../client_handler/', + r'./../../subprocess/', # libcefpythonapp + r'./../../../cpp_utils/' + ], + + libraries=[ + 'client_handler', + 'cef_dll_wrapper', + 'cefpythonapp', + 'cpp_utils' + ], + + # Loading libcef.so will only work when running scripts from the same + # directory that libcef.so resides in when you put "./" in here. + # runtime_library_dirs=[ + # './' + #], + + extra_compile_args=[], + extra_link_args=[], + + # Defining macros: + # define_macros = [("UNICODE","1"), ("_UNICODE","1"), ] +)] + +setup( + name = 'cefpython_py%s' % PYTHON_VERSION, + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules +) diff --git a/cefpython/cef3/subprocess/.gitignore b/cefpython/cef3/subprocess/.gitignore new file mode 100644 index 00000000..96f876bd --- /dev/null +++ b/cefpython/cef3/subprocess/.gitignore @@ -0,0 +1,4 @@ +*.o +*.a +subprocess +subprocess.dSYM/ diff --git a/cefpython/cef3/subprocess/Makefile b/cefpython/cef3/subprocess/Makefile new file mode 100644 index 00000000..13611e97 --- /dev/null +++ b/cefpython/cef3/subprocess/Makefile @@ -0,0 +1,34 @@ +# -g - extra debug information +# -O1 - more precise backtraces +# -fPIC - required when using -shared option, required for use with Cython +# -Wall - show important warnings +# -Werror - treat warnings as errors + +UNAME_S = $(shell uname -s) + +INC = -I./../ -I/usr/include/gtk-2.0 \ + -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \ + -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \ + -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \ + -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ + -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ + -I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \ + -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include + +ifeq ($(UNAME_S), Linux) + LIB = -L./../linux/setup/lib_64bit -L./../linux/setup/lib_32bit \ + -L./../linux/binaries_64bit -L./../linux/binaries_32bit +else ifeq ($(UNAME_S), Darwin) + LIB = -L./../mac/setup/lib_64bit -L./../mac/setup/lib_32bit \ + -L./../mac/binaries_64bit/ \ + -L./../mac/binaries_32bit/ +endif + +CCFLAGS = -g -Wall -Werror -DRENDERER_PROCESS $(CEF_CCFLAGS) + + +subprocess: + # -fPIC is required only for libraries included by Cython. + g++ $(CCFLAGS) $(INC) $(LIB) main.cpp cefpython_app.cpp \ + v8function_handler.cpp v8utils.cpp javascript_callback.cpp \ + -lcef_dll_wrapper -lcef -o subprocess -Wl,-rpath,. diff --git a/cefpython/cef3/subprocess/Makefile-libcefpythonapp b/cefpython/cef3/subprocess/Makefile-libcefpythonapp new file mode 100644 index 00000000..5b89ceee --- /dev/null +++ b/cefpython/cef3/subprocess/Makefile-libcefpythonapp @@ -0,0 +1,32 @@ +# -g - extra debug information +# -O1 - more precise backtraces +# -fPIC - required when using -shared option, required for use with Cython +# -Wall - show important warnings +# -Werror - treat warnings as errors + +# Cython compiler options: +# -fPIC -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions \ +# -Wl,-z,relro + +CC = g++ +CCFLAGS = -g -fPIC -Wall -Werror -DBROWSER_PROCESS $(CEF_CCFLAGS) + +SRC = cefpython_app.cpp v8function_handler.cpp v8utils.cpp \ + javascript_callback.cpp +OBJ = $(SRC:.cpp=.o) +OUT = libcefpythonapp.a + +INC = -I./../ -I/usr/include/python2.7 -I/usr/include/gtk-2.0 \ + -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \ + -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \ + -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \ + -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ + -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ + -I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \ + -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include + +.cpp.o: + $(CC) $(CCFLAGS) $(INC) -c $< -o $@ + +$(OUT): $(OBJ) + ar rcs $(OUT) $(OBJ) diff --git a/cefpython/cef3/subprocess/cefpython_app.cpp b/cefpython/cef3/subprocess/cefpython_app.cpp new file mode 100644 index 00000000..a08d480d --- /dev/null +++ b/cefpython/cef3/subprocess/cefpython_app.cpp @@ -0,0 +1,610 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// BROWSER_PROCESS macro is defined when compiling the libcefpythonapp library. +// RENDERER_PROCESS macro is define when compiling the subprocess executable. + +#ifdef BROWSER_PROCESS +#include "cefpython_public_api.h" +#endif + +#include "cefpython_app.h" +#include "util.h" +#include "include/cef_runnable.h" +#include "DebugLog.h" +#include "LOG_DEBUG.h" +#include +#include +#include "v8utils.h" +#include "javascript_callback.h" +#include "v8function_handler.h" + +bool g_debug = false; +std::string g_logFile = "debug.log"; + +CefPythonApp::CefPythonApp() { +#ifdef BROWSER_PROCESS + cefpython_GetDebugOptions(&g_debug, &g_logFile); +#endif +} + +// ----------------------------------------------------------------------------- +// CefApp +// ----------------------------------------------------------------------------- + +void CefPythonApp::OnBeforeCommandLineProcessing( + const CefString& process_type, + CefRefPtr command_line) { +#ifdef BROWSER_PROCESS + // This is included only in the Browser process, when building + // the libcefpythonapp library. + if (process_type.empty()) { + // Empty proc type, so this must be the main browser process. + App_OnBeforeCommandLineProcessing_BrowserProcess(command_line); + } +#endif + std::string process_name = process_type.ToString(); + if (process_name.empty()) { + process_name = "browser"; + } + std::string logMessage = "Command line string for the "; + logMessage.append(process_name); + logMessage.append(" process: "); + std::string clString = command_line->GetCommandLineString().ToString(); + logMessage.append(clString.c_str()); + // OnBeforeCommandLineProcessing() is called before + // CefRenderHandler::OnRenderThreadCreated() which sets + // the debug options. Thus debugging will always be Off + // at the time this method is called. The fix for that + // is to keep the command line string somewhere and call + // DebugLog later in OnRenderThreadCreated(). + if (g_debug) { + DebugLog(logMessage.c_str()); + } else { + commandLineString_ = logMessage; + } +} + +void CefPythonApp::OnRegisterCustomSchemes( + CefRefPtr registrar) { +} + +CefRefPtr CefPythonApp::GetResourceBundleHandler() { + return NULL; +} + +CefRefPtr CefPythonApp::GetBrowserProcessHandler() { + return this; +} + +CefRefPtr CefPythonApp::GetRenderProcessHandler() { + return this; +} + +// ----------------------------------------------------------------------------- +// CefBrowserProcessHandler +// ----------------------------------------------------------------------------- + +void CefPythonApp::OnContextInitialized() { + REQUIRE_UI_THREAD(); +} + +void CefPythonApp::OnBeforeChildProcessLaunch( + CefRefPtr command_line) { +#ifdef BROWSER_PROCESS + // This is included only in the Browser process, when building + // the libcefpythonapp library. + BrowserProcessHandler_OnBeforeChildProcessLaunch(command_line); +#endif +} + +/// +// Called on the browser process IO thread after the main thread has been +// created for a new render process. Provides an opportunity to specify extra +// information that will be passed to +// CefRenderProcessHandler::OnRenderThreadCreated() in the render process. Do +// not keep a reference to |extra_info| outside of this method. +/// +void CefPythonApp::OnRenderProcessThreadCreated( + CefRefPtr extra_info) { + // If you have an existing CefListValue that you would like + // to provide, do this: + // | extra_info = mylist.get() + // The equivalent in Cython is: + // | extra_info.Assign(mylist.get()) + REQUIRE_IO_THREAD(); + extra_info->SetBool(0, g_debug); + extra_info->SetString(1, g_logFile); +#ifdef BROWSER_PROCESS + // This is included only in the Browser process, when building + // the libcefpythonapp library. + BrowserProcessHandler_OnRenderProcessThreadCreated(extra_info); +#endif +} + +// ----------------------------------------------------------------------------- +// CefRenderProcessHandler +// ----------------------------------------------------------------------------- + +/// +// Called after the render process main thread has been created. |extra_info| +// is a read-only value originating from +// CefBrowserProcessHandler::OnRenderProcessThreadCreated(). Do not keep a +// reference to |extra_info| outside of this method. +/// +void CefPythonApp::OnRenderThreadCreated(CefRefPtr extra_info) { + if (extra_info->GetType(0) == VTYPE_BOOL) { + g_debug = extra_info->GetBool(0); + if (g_debug) { + FILELog::ReportingLevel() = logDEBUG; + } else { + // In reality this disables logging in LOG_DEBUG.h, as + // we're using only LOG_DEBUG macro. + FILELog::ReportingLevel() = logERROR; + } + } + if (extra_info->GetType(1) == VTYPE_STRING) { + g_logFile = extra_info->GetString(1).ToString(); + } + if (!commandLineString_.empty()) { + // See comment in OnBeforeCommandLineProcessing(). + DebugLog(commandLineString_.c_str()); + commandLineString_ = ""; + } +} + +void CefPythonApp::OnWebKitInitialized() { +} + +void CefPythonApp::OnBrowserCreated(CefRefPtr browser) { +} + +void CefPythonApp::OnBrowserDestroyed(CefRefPtr browser) { + DebugLog("Renderer: OnBrowserDestroyed()"); + RemoveJavascriptBindings(browser); +} + +bool CefPythonApp::OnBeforeNavigation(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + cef_navigation_type_t navigation_type, + bool is_redirect) { + return false; +} + +void CefPythonApp::OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) { + DebugLog("Renderer: OnContextCreated()"); + CefRefPtr message = CefProcessMessage::Create( + "OnContextCreated"); + CefRefPtr arguments = message->GetArgumentList(); + /* + Sending int64 type using process messaging would require + converting it to a string or a binary, or you could send + two ints, see this topic: + http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10869 + */ + /* + // Example of converting int64 to string. Still need an + // example of converting it back from string. + std::string logMessage = "OnContextCreated(): frameId="; + stringstream stream; + int64 value = frame->GetIdentifier(); + stream << value; + logMessage.append(stream.str()); + DebugLog(logMessage.c_str()); + */ + // TODO: losing int64 precision, the solution is to convert + // it to string and then in the Browser process back + // from string to int64. But it is rather unlikely + // that number of frames will exceed int range, so + // casting it to int for now. + arguments->SetInt(0, (int)(frame->GetIdentifier())); + browser->SendProcessMessage(PID_BROWSER, message); + CefRefPtr jsBindings = GetJavascriptBindings(browser); + if (jsBindings.get()) { + // Javascript bindings are most probably not yet set for + // the main frame, they will be set a moment later due to + // process messaging delay. The code seems to be executed + // only for iframes. + if (frame->IsMain()) { + DoJavascriptBindingsForFrame(browser, frame, context); + } else { + if (jsBindings->HasKey("bindToFrames") + && jsBindings->GetType("bindToFrames") == VTYPE_BOOL + && jsBindings->GetBool("bindToFrames")) { + DoJavascriptBindingsForFrame(browser, frame, context); + } + } + } +} + +void CefPythonApp::OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) { + DebugLog("Renderer: OnContextReleased()"); + CefRefPtr message; + CefRefPtr arguments; + // ------------------------------------------------------------------------ + // 1. Send "OnContextReleased" message. + // ------------------------------------------------------------------------ + message = CefProcessMessage::Create("OnContextReleased"); + arguments = message->GetArgumentList(); + arguments->SetInt(0, browser->GetIdentifier()); + // TODO: losing int64 precision, the solution is to convert + // it to string and then in the Browser process back + // from string to int64. But it is rather unlikely + // that number of frames will exceed int range, so + // casting it to int for now. + arguments->SetInt(1, (int)(frame->GetIdentifier())); + // Should we send the message using current "browser" + // when this is not the main frame? It could fail, so + // it is more reliable to always use the main browser. + browser->SendProcessMessage(PID_BROWSER, message); + // ------------------------------------------------------------------------ + // 2. Remove python callbacks for a frame. + // ------------------------------------------------------------------------ + // If this is the main frame then the message won't arrive + // to the browser process, as browser is being destroyed, + // but it doesn't matter because in LifespanHandler_BeforeClose() + // we're calling RemovePythonCallbacksForBrowser(). + message = CefProcessMessage::Create("RemovePythonCallbacksForFrame"); + arguments = message->GetArgumentList(); + // TODO: int64 precision lost + arguments->SetInt(0, (int)(frame->GetIdentifier())); + browser->SendProcessMessage(PID_BROWSER, message); + // ------------------------------------------------------------------------ + // 3. Clear javascript callbacks. + // ------------------------------------------------------------------------ + RemoveJavascriptCallbacksForFrame(frame); +} + +void CefPythonApp::OnUncaughtException(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) { +} + +void CefPythonApp::OnFocusedNodeChanged(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr node) { +} + +/// +// Called when a new message is received from a different process. Return true +// if the message was handled or false otherwise. Do not keep a reference to +// or attempt to access the message outside of this callback. +/// +bool CefPythonApp::OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + std::string messageName = message->GetName().ToString(); + std::string logMessage = "Renderer: OnProcessMessageReceived(): "; + logMessage.append(messageName.c_str()); + DebugLog(logMessage.c_str()); + CefRefPtr args = message->GetArgumentList(); + if (messageName == "DoJavascriptBindings") { + if (args->GetSize() == 1 + && args->GetType(0) == VTYPE_DICTIONARY + && args->GetDictionary(0)->IsValid()) { + // Is it necessary to make a copy? It won't harm. + SetJavascriptBindings(browser, + args->GetDictionary(0)->Copy(false)); + DoJavascriptBindingsForBrowser(browser); + } else { + DebugLog("Renderer: OnProcessMessageReceived(): invalid arguments,"\ + " messageName=DoJavascriptBindings"); + return false; + } + } else if (messageName == "ExecuteJavascriptCallback") { + if (args->GetType(0) == VTYPE_INT) { + int jsCallbackId = args->GetInt(0); + CefRefPtr jsArgs; + if (args->IsReadOnly()) { + jsArgs = args->Copy(); + } else { + jsArgs = args; + } + // Remove jsCallbackId. + jsArgs->Remove(0); + ExecuteJavascriptCallback(jsCallbackId, jsArgs); + } else { + DebugLog("Renderer: OnProcessMessageReceived: invalid arguments," \ + "expected first argument to be a javascript callback " \ + "(int)"); + return false; + } + } + return true; +} + +void CefPythonApp::SetJavascriptBindings(CefRefPtr browser, + CefRefPtr data) { + javascriptBindings_[browser->GetIdentifier()] = data; +} + +CefRefPtr CefPythonApp::GetJavascriptBindings( + CefRefPtr browser) { + int browserId = browser->GetIdentifier(); + if (javascriptBindings_.find(browserId) != javascriptBindings_.end()) { + return javascriptBindings_[browserId]; + } + return NULL; +} + +void CefPythonApp::RemoveJavascriptBindings(CefRefPtr browser) { + int browserId = browser->GetIdentifier(); + if (javascriptBindings_.find(browserId) != javascriptBindings_.end()) { + javascriptBindings_.erase(browserId); + } +} + +bool CefPythonApp::BindedFunctionExists(CefRefPtr browser, + const CefString& functionName) { + CefRefPtr jsBindings = GetJavascriptBindings(browser); + if (!jsBindings.get()) { + return false; + } + std::string strFunctionName = functionName.ToString(); + size_t dotPosition = strFunctionName.find("."); + if (std::string::npos != dotPosition) { + // This is a method call, functionName == "object.method". + CefString objectName(strFunctionName.substr(0, dotPosition)); + CefString methodName(strFunctionName.substr(dotPosition + 1, + std::string::npos)); + if (!(jsBindings->HasKey("objects") + && jsBindings->GetType("objects") == VTYPE_DICTIONARY)) { + DebugLog("Renderer: BindedFunctionExists() FAILED: "\ + "objects dictionary not found"); + return false; + } + CefRefPtr objects = \ + jsBindings->GetDictionary("objects"); + if (objects->HasKey(objectName)) { + if (!(objects->GetType(objectName) == VTYPE_DICTIONARY)) { + DebugLog("Renderer: BindedFunctionExists() FAILED: "\ + "objects dictionary has invalid type"); + return false; + } + CefRefPtr methods = \ + objects->GetDictionary(objectName); + return methods->HasKey(methodName); + } else { + return false; + } + } else { + // This is a function call. + if (!(jsBindings->HasKey("functions") + && jsBindings->GetType("functions") == VTYPE_DICTIONARY)) { + DebugLog("Renderer: BindedFunctionExists() FAILED: "\ + "functions dictionary not found"); + return false; + } + CefRefPtr functions = \ + jsBindings->GetDictionary("functions"); + return functions->HasKey(functionName); + } +} + +void CefPythonApp::DoJavascriptBindingsForBrowser( + CefRefPtr browser) { + // get frame + // get context + // if bindToFrames is true loop through all frames, + // otherwise just the main frame. + // post task on a valid v8 thread + CefRefPtr jsBindings = GetJavascriptBindings(browser); + if (!jsBindings.get()) { + // Bindings must be set before this function is called. + DebugLog("Renderer: DoJavascriptBindingsForBrowser() FAILED: " \ + "bindings not set"); + return; + } + std::vector frameIds; + std::vector frameNames; + if (jsBindings->HasKey("bindToFrames") + && jsBindings->GetType("bindToFrames") == VTYPE_BOOL + && jsBindings->GetBool("bindToFrames")) { + // GetFrameIdentifiers() is buggy, returns always a vector + // filled with zeroes (as of revision 1448). Use GetFrameNames() + // instead. + browser->GetFrameNames(frameNames); + for (std::vector::iterator it = frameNames.begin(); \ + it != frameNames.end(); ++it) { + CefRefPtr frame = browser->GetFrame(*it); + if (frame.get()) { + frameIds.push_back(frame->GetIdentifier()); + // | printf("GetFrameNames(): frameId = %lu\n", + // | frame->GetIdentifier()); + } + } + } + // BUG in CEF: + // GetFrameNames() does not return the main frame (as of revision 1448). + // Make it work for the future when this bug gets fixed. + std::vector::iterator find_it = std::find( + frameIds.begin(), frameIds.end(), + browser->GetMainFrame()->GetIdentifier()); + if (find_it == frameIds.end()) { + // Main frame not found in frameIds vector, add it now. + // | printf("Adding main frame to frameIds: %lu\n", + // | browser->GetMainFrame()->GetIdentifier()); + frameIds.push_back(browser->GetMainFrame()->GetIdentifier()); + } + if (!frameIds.size()) { + DebugLog("Renderer: DoJavascriptBindingsForBrowser() FAILED: " \ + "frameIds.size() == 0"); + return; + } + for (std::vector::iterator it = frameIds.begin(); \ + it != frameIds.end(); ++it) { + if (*it <= 0) { + // GetFrameIdentifiers() bug that returned a vector + // filled with zeros. This problem was fixed by using' + // GetFrameNames() so this block of code should not + // be executed anymore. + DebugLog("Renderer: DoJavascriptBindingsForBrowser() WARNING: " \ + "frameId <= 0"); + // printf("[CEF Python] Renderer: frameId = %lli\n", *it); + continue; + } + CefRefPtr frame = browser->GetFrame(*it); + if (!frame.get()) { + DebugLog("Renderer: DoJavascriptBindingsForBrowser() WARNING: " \ + "GetFrame() failed"); + continue; + } + CefRefPtr context = frame->GetV8Context(); + CefRefPtr taskRunner = context->GetTaskRunner(); + taskRunner->PostTask(NewCefRunnableMethod( + this, &CefPythonApp::DoJavascriptBindingsForFrame, + browser, frame, context)); + } +} + +void CefPythonApp::DoJavascriptBindingsForFrame(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) { + CefRefPtr jsBindings = GetJavascriptBindings(browser); + if (!jsBindings.get()) { + // Bindings may not yet be set, it's okay. + DebugLog("Renderer: DoJavascriptBindingsForFrame(): bindings not set"); + return; + } + DebugLog("Renderer: DoJavascriptBindingsForFrame(): bindings are set"); + if (!(jsBindings->HasKey("functions") + && jsBindings->GetType("functions") == VTYPE_DICTIONARY + && jsBindings->HasKey("properties") + && jsBindings->GetType("properties") == VTYPE_DICTIONARY + && jsBindings->HasKey("objects") + && jsBindings->GetType("objects") == VTYPE_DICTIONARY + && jsBindings->HasKey("bindToFrames") + && jsBindings->GetType("bindToFrames") == VTYPE_BOOL)) { + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED: " \ + "invalid data [1]"); + return; + } + + // A context must be explicitly entered before creating a + // V8 Object, Array, Function or Date asynchronously. + // NOTE: you cannot call CefV8Context::GetEnteredContext + // or GetCurrentContext when CefV8Context::InContext + // returns false, as it will result in crashes. + bool didEnterContext = false; + if (!CefV8Context::InContext()) { + if (!context->IsValid()) { + // BUG in CEF (Issue 130), the "context" provided by CEF may + // not be valid. May be a timing issue. Or may be caused by + // a redirect to a different origin and that creates a new + // renderer process. + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED:"\ + " V8 context provided by CEF is invalid"); + return; + } + context->Enter(); + didEnterContext = true; + } + CefRefPtr functions = \ + jsBindings->GetDictionary("functions"); + CefRefPtr properties = \ + jsBindings->GetDictionary("properties"); + CefRefPtr objects = \ + jsBindings->GetDictionary("objects"); + // Here in this function we bind only for the current frame. + // | bool bindToFrames = jsBindings->GetBool("bindToFrames"); + if (!(functions->IsValid() && properties->IsValid() + && objects->IsValid())) { + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED: " \ + "invalid data [2]"); + if (didEnterContext) + context->Exit(); + return; + } + CefRefPtr v8Window = context->GetGlobal(); + CefRefPtr v8Function; + CefRefPtr v8FunctionHandler(new V8FunctionHandler(this, 0)); + // FUNCTIONS. + std::vector functionsVector; + if (!functions->GetKeys(functionsVector)) { + DebugLog("Renderer: DoJavascriptBindingsForFrame(): " \ + "functions->GetKeys() FAILED"); + if (didEnterContext) + context->Exit(); + return; + } + for (std::vector::iterator it = functionsVector.begin(); \ + it != functionsVector.end(); ++it) { + CefString functionName = *it; + v8Function = CefV8Value::CreateFunction(functionName, + v8FunctionHandler); + v8Window->SetValue(functionName, v8Function, + V8_PROPERTY_ATTRIBUTE_NONE); + } + // PROPERTIES. + CefRefPtr v8Properties = CefDictionaryValueToV8Value( + properties); + std::vector v8Keys; + if (!v8Properties->GetKeys(v8Keys)) { + DebugLog("DoJavascriptBindingsForFrame() FAILED: " \ + "v8Properties->GetKeys() failed"); + if (didEnterContext) + context->Exit(); + return; + } + for (std::vector::iterator it = v8Keys.begin(); \ + it != v8Keys.end(); ++it) { + CefString v8Key = *it; + CefRefPtr v8Value = v8Properties->GetValue(v8Key); + v8Window->SetValue(v8Key, v8Value, V8_PROPERTY_ATTRIBUTE_NONE); + } + // OBJECTS AND ITS METHODS. + std::vector objectsVector; + if (!objects->GetKeys(objectsVector)) { + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED: " \ + "objects->GetKeys() failed"); + if (didEnterContext) + context->Exit(); + return; + } + for (std::vector::iterator it = objectsVector.begin(); \ + it != objectsVector.end(); ++it) { + CefString objectName = *it; + CefRefPtr v8Object = CefV8Value::CreateObject(NULL); + v8Window->SetValue(objectName, v8Object, V8_PROPERTY_ATTRIBUTE_NONE); + // METHODS. + if (!(objects->GetType(objectName) == VTYPE_DICTIONARY)) { + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED: " \ + "objects->GetType() != VTYPE_DICTIONARY"); + if (didEnterContext) + context->Exit(); + return; + } + CefRefPtr methods = \ + objects->GetDictionary(objectName); + std::vector methodsVector; + if (!(methods->IsValid() && methods->GetKeys(methodsVector))) { + DebugLog("Renderer: DoJavascriptBindingsForFrame() FAILED: " \ + "methods->GetKeys() failed"); + if (didEnterContext) + context->Exit(); + return; + } + for (std::vector::iterator it = methodsVector.begin(); \ + it != methodsVector.end(); ++it) { + CefString methodName = *it; + // fullMethodName = "object.method" + std::string fullMethodName = objectName.ToString().append(".") \ + .append(methodName.ToString()); + v8Function = CefV8Value::CreateFunction(fullMethodName, + v8FunctionHandler); + v8Object->SetValue(methodName, v8Function, + V8_PROPERTY_ATTRIBUTE_NONE); + } + } + // END. + if (didEnterContext) + context->Exit(); +} diff --git a/cefpython/cef3/subprocess/cefpython_app.h b/cefpython/cef3/subprocess/cefpython_app.h new file mode 100644 index 00000000..7cf2a8ff --- /dev/null +++ b/cefpython/cef3/subprocess/cefpython_app.h @@ -0,0 +1,132 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include "include/cef_app.h" +#include + +// CefPythonApp class is instantiated in subprocess and in +// cefpython.pyx for the browser process, so the code is shared. +// Using printf() in CefRenderProcessHandler won't work, use +// the DebugLog() function instead, it will write the message +// to the "debug.log" file. + +/// +// Implement this interface to provide handler implementations. Methods will be +// called by the process and/or thread indicated. +/// +/*--cef(source=client,no_debugct_check)--*/ +class CefPythonApp : + public CefApp, + public CefBrowserProcessHandler, + public CefRenderProcessHandler { + public: + CefPythonApp(); + + virtual void OnBeforeCommandLineProcessing( + const CefString& process_type, + CefRefPtr command_line) OVERRIDE; + + virtual void OnRegisterCustomSchemes( + CefRefPtr registrar) OVERRIDE; + + virtual CefRefPtr GetResourceBundleHandler() + OVERRIDE; + + virtual CefRefPtr GetBrowserProcessHandler() + OVERRIDE; + + virtual CefRefPtr GetRenderProcessHandler() + OVERRIDE; + + // --------------------------------------------------------------------------- + // CefBrowserProcessHandler + // --------------------------------------------------------------------------- + + virtual void OnContextInitialized() OVERRIDE; + + virtual void OnBeforeChildProcessLaunch( + CefRefPtr command_line) OVERRIDE; + + virtual void OnRenderProcessThreadCreated( + CefRefPtr extra_info) OVERRIDE; + + // --------------------------------------------------------------------------- + // CefRenderProcessHandler + // --------------------------------------------------------------------------- + + virtual void OnRenderThreadCreated(CefRefPtr extra_info) + OVERRIDE; + + virtual void OnWebKitInitialized() + OVERRIDE; + + virtual void OnBrowserCreated(CefRefPtr browser) + OVERRIDE; + + virtual void OnBrowserDestroyed(CefRefPtr browser) + OVERRIDE; + + virtual bool OnBeforeNavigation(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + cef_navigation_type_t navigation_type, + bool is_redirect) + OVERRIDE; + + virtual void OnContextCreated(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) + OVERRIDE; + + virtual void OnContextReleased(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) + OVERRIDE; + + virtual void OnUncaughtException(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context, + CefRefPtr exception, + CefRefPtr stackTrace) + OVERRIDE; + + virtual void OnFocusedNodeChanged(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr node) + OVERRIDE; + + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) + OVERRIDE; + + // --------------------------------------------------------------------------- + // Javascript bindings + // --------------------------------------------------------------------------- + + virtual void SetJavascriptBindings(CefRefPtr browser, + CefRefPtr data); + virtual CefRefPtr GetJavascriptBindings( + CefRefPtr browser); + + virtual void RemoveJavascriptBindings(CefRefPtr browser); + + virtual bool BindedFunctionExists(CefRefPtr browser, + const CefString& funcName); + + virtual void DoJavascriptBindingsForBrowser(CefRefPtr browser); + + virtual void DoJavascriptBindingsForFrame(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context); + +protected: + std::map > javascriptBindings_; + std::string commandLineString_; + +private: + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(CefPythonApp); +}; diff --git a/cefpython/cef3/subprocess/javascript_callback.cpp b/cefpython/cef3/subprocess/javascript_callback.cpp new file mode 100644 index 00000000..ac673c0e --- /dev/null +++ b/cefpython/cef3/subprocess/javascript_callback.cpp @@ -0,0 +1,104 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "javascript_callback.h" +#include +#include +#include "DebugLog.h" +#include "v8utils.h" +#include "cefpython_app.h" + +template +inline std::string AnyToString(const T& value) +{ + std::ostringstream oss; + oss << value; + return oss.str(); +} + +typedef std::map, CefRefPtr > > + JavascriptCallbackMap; + +JavascriptCallbackMap g_jsCallbackMap; +int g_jsCallbackMaxId = 0; + +CefString PutJavascriptCallback( + CefRefPtr frame, CefRefPtr jsCallback) { + // Returns a "####cefpython####" string followed by json encoded data. + // {"what":"javascript-callback","callbackId":123, + // "frameId":123,"functionName":"xx"} + int callbackId = ++g_jsCallbackMaxId; + int64 frameId = frame->GetIdentifier(); + CefString functionName = jsCallback->GetFunctionName(); + std::string strCallbackId = "####cefpython####"; + strCallbackId.append("{"); + // JSON format allows only for double quotes. + strCallbackId.append("\"what\":\"javascript-callback\""); + strCallbackId.append(",\"callbackId\":").append(AnyToString(callbackId)); + strCallbackId.append(",\"frameId\":").append(AnyToString(frameId)); + strCallbackId.append(",\"functionName\":\"").append(functionName) \ + .append("\""); + strCallbackId.append("}"); + g_jsCallbackMap.insert(std::make_pair( + callbackId, + std::make_pair(frame, jsCallback))); + return strCallbackId; +} + +bool ExecuteJavascriptCallback(int callbackId, CefRefPtr args) { + if (g_jsCallbackMap.empty()) { + DebugLog("Renderer: ExecuteJavascriptCallback() FAILED: " \ + "callback map is empty"); + return false; + } + JavascriptCallbackMap::const_iterator it = g_jsCallbackMap.find( + callbackId); + if (it == g_jsCallbackMap.end()) { + std::string logMessage = "Renderer: ExecuteJavascriptCallback() " + "FAILED: callback not found, id="; + logMessage.append(AnyToString(callbackId)); + DebugLog(logMessage.c_str()); + return false; + } + CefRefPtr frame = it->second.first; + CefRefPtr callback = it->second.second; + CefRefPtr context = frame->GetV8Context(); + context->Enter(); + CefV8ValueList v8Arguments = CefListValueToCefV8ValueList(args); + CefRefPtr v8ReturnValue = callback->ExecuteFunction( + NULL, v8Arguments); + if (v8ReturnValue.get()) { + context->Exit(); + return true; + } else { + context->Exit(); + DebugLog("Renderer: ExecuteJavascriptCallback() FAILED: " \ + "callback->ExecuteFunction() FAILED"); + return false; + } +} + +void RemoveJavascriptCallbacksForFrame(CefRefPtr frame) { + if (g_jsCallbackMap.empty()) { + return; + } + JavascriptCallbackMap::iterator it = g_jsCallbackMap.begin(); + int64 frameId = frame->GetIdentifier(); + while (it != g_jsCallbackMap.end()) { + if (it->second.first->GetIdentifier() == frameId) { + // Pass current iterator and increment it after passing + // to the function, but before erase() is called, this + // is important for it to work in a loop. You can't do this: + // | if (..) erase(it); + // | ++it; + // This would cause an infinite loop. + g_jsCallbackMap.erase(it++); + DebugLog("Renderer: RemoveJavascriptCallbacksForFrame(): " \ + "removed js callback from the map"); + } else { + ++it; + } + } +} diff --git a/cefpython/cef3/subprocess/javascript_callback.h b/cefpython/cef3/subprocess/javascript_callback.h new file mode 100644 index 00000000..6cc0b63f --- /dev/null +++ b/cefpython/cef3/subprocess/javascript_callback.h @@ -0,0 +1,13 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include "include/cef_v8.h" + +CefString PutJavascriptCallback( + CefRefPtr frame, CefRefPtr jsCallback); + +bool ExecuteJavascriptCallback(int callbackId, CefRefPtr args); + +void RemoveJavascriptCallbacksForFrame(CefRefPtr frame); diff --git a/cefpython/cef3/subprocess/libcefpythonapp_py27_32bit.vcproj b/cefpython/cef3/subprocess/libcefpythonapp_py27_32bit.vcproj new file mode 100644 index 00000000..6bea39c1 --- /dev/null +++ b/cefpython/cef3/subprocess/libcefpythonapp_py27_32bit.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/subprocess/libcefpythonapp_py27_64bit.vcproj b/cefpython/cef3/subprocess/libcefpythonapp_py27_64bit.vcproj new file mode 100644 index 00000000..45fa3415 --- /dev/null +++ b/cefpython/cef3/subprocess/libcefpythonapp_py27_64bit.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/subprocess/libcefpythonapp_py34_32bit.vcproj b/cefpython/cef3/subprocess/libcefpythonapp_py34_32bit.vcproj new file mode 100644 index 00000000..002c4e38 --- /dev/null +++ b/cefpython/cef3/subprocess/libcefpythonapp_py34_32bit.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/subprocess/main.cpp b/cefpython/cef3/subprocess/main.cpp new file mode 100644 index 00000000..e1cd101a --- /dev/null +++ b/cefpython/cef3/subprocess/main.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "cefpython_app.h" + +#if defined(OS_WIN) + +#include +int APIENTRY wWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) + +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + CefMainArgs mainArgs(hInstance); + +#else // Mac, Linux + +int main(int argc, char **argv) +{ + CefMainArgs mainArgs(argc, argv); + +#endif + + CefRefPtr app(new CefPythonApp); + int exitCode = CefExecuteProcess(mainArgs, app.get()); + return exitCode; +} diff --git a/cefpython/cef3/subprocess/subprocess_32bit.vcproj b/cefpython/cef3/subprocess/subprocess_32bit.vcproj new file mode 100644 index 00000000..fd1d9930 --- /dev/null +++ b/cefpython/cef3/subprocess/subprocess_32bit.vcproj @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/subprocess/subprocess_64bit.vcproj b/cefpython/cef3/subprocess/subprocess_64bit.vcproj new file mode 100644 index 00000000..1f1c1028 --- /dev/null +++ b/cefpython/cef3/subprocess/subprocess_64bit.vcproj @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cef3/subprocess/v8function_handler.cpp b/cefpython/cef3/subprocess/v8function_handler.cpp new file mode 100644 index 00000000..ce49752a --- /dev/null +++ b/cefpython/cef3/subprocess/v8function_handler.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#include "cefpython_app.h" +#include "v8utils.h" +#include "DebugLog.h" + +bool V8FunctionHandler::Execute(const CefString& functionName, + CefRefPtr thisObject, + const CefV8ValueList& v8Arguments, + CefRefPtr& returnValue, + CefString& exception) { + if (!CefV8Context::InContext()) { + // CefV8Context::GetCurrentContext may not be called when + // not in a V8 context. + DebugLog("Renderer: V8FunctionHandler::Execute() FAILED:"\ + " not inside a V8 context"); + return false; + } + CefRefPtr context = CefV8Context::GetCurrentContext(); + CefRefPtr browser = context.get()->GetBrowser(); + CefRefPtr frame = context.get()->GetFrame(); + if (pythonCallbackId_) { + DebugLog("Renderer: V8FunctionHandler::Execute(): python callback"); + CefRefPtr functionArguments = V8ValueListToCefListValue( + v8Arguments); + CefRefPtr processMessage = \ + CefProcessMessage::Create("ExecutePythonCallback"); + CefRefPtr messageArguments = \ + processMessage->GetArgumentList(); + messageArguments->SetInt(0, pythonCallbackId_); + messageArguments->SetList(1, functionArguments); + browser->SendProcessMessage(PID_BROWSER, processMessage); + returnValue = CefV8Value::CreateNull(); + return true; + } else { + DebugLog("Renderer: V8FunctionHandler::Execute(): js binding"); + if (!(cefPythonApp_.get() \ + && cefPythonApp_->BindedFunctionExists( \ + browser, functionName))) { + exception = std::string("[CEF Python] " \ + "V8FunctionHandler::Execute() FAILED: " \ + "function does not exist: ").append(functionName) \ + .append("()"); + // Must return true for the exception to be thrown. + return true; + } + CefRefPtr functionArguments = V8ValueListToCefListValue( + v8Arguments); + // TODO: losing int64 precision here. + int frameId = (int)frame->GetIdentifier(); + CefRefPtr processMessage = \ + CefProcessMessage::Create("V8FunctionHandler::Execute"); + CefRefPtr messageArguments = \ + processMessage->GetArgumentList(); + messageArguments->SetInt(0, frameId); + messageArguments->SetString(1, functionName); + messageArguments->SetList(2, functionArguments); + browser->SendProcessMessage(PID_BROWSER, processMessage); + returnValue = CefV8Value::CreateNull(); + return true; + } +} diff --git a/cefpython/cef3/subprocess/v8function_handler.h b/cefpython/cef3/subprocess/v8function_handler.h new file mode 100644 index 00000000..d268a967 --- /dev/null +++ b/cefpython/cef3/subprocess/v8function_handler.h @@ -0,0 +1,29 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include "include/cef_v8.h" +#include "util.h" + +class CefPythonApp; + +class V8FunctionHandler + : public CefV8Handler { +public: + V8FunctionHandler(CefRefPtr cefPythonApp, + int pythonCallbackId) + : cefPythonApp_(cefPythonApp), + pythonCallbackId_(pythonCallbackId) { + } + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE; +protected: + CefRefPtr cefPythonApp_; + int pythonCallbackId_; +private: + IMPLEMENT_REFCOUNTING(V8FunctionHandler); +}; diff --git a/cefpython/cef3/subprocess/v8utils.cpp b/cefpython/cef3/subprocess/v8utils.cpp new file mode 100644 index 00000000..1d5bd461 --- /dev/null +++ b/cefpython/cef3/subprocess/v8utils.cpp @@ -0,0 +1,394 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +// CefListValue->SetXxxx() functions need first param to be be cast +// to (int) because GetSize() returns size_t and generates a warning +// when compiling on VS2008 for x64 platform. Issue reported here: +// https://code.google.com/p/cefpython/issues/detail?id=165 + +#include "v8utils.h" +#include "javascript_callback.h" +#include "DebugLog.h" +#include "cefpython_app.h" +#include + +// ---------------------------------------------------------------------------- +// V8 values to CEF values. +// ---------------------------------------------------------------------------- + +CefRefPtr V8ValueListToCefListValue( + const CefV8ValueList& v8List) { + // typedef std::vector > CefV8ValueList; + CefRefPtr listValue = CefListValue::Create(); + for (CefV8ValueList::const_iterator it = v8List.begin(); it != v8List.end(); \ + ++it) { + CefRefPtr v8Value = *it; + V8ValueAppendToCefListValue(v8Value, listValue); + } + return listValue; +} + +void V8ValueAppendToCefListValue(CefRefPtr v8Value, + CefRefPtr listValue, + int nestingLevel) { + if (!v8Value->IsValid()) { + DebugLog("V8ValueAppendToCefListValue(): IsValid() FAILED"); + return; + } + if (nestingLevel > 8) { + DebugLog("V8ValueAppendToCefListValue(): WARNING: max nesting level (8) " \ + "exceeded"); + return; + } + if (v8Value->IsUndefined() || v8Value->IsNull()) { + listValue->SetNull((int)listValue->GetSize()); + } else if (v8Value->IsBool()) { + listValue->SetBool((int)listValue->GetSize(), v8Value->GetBoolValue()); + } else if (v8Value->IsInt()) { + listValue->SetInt((int)listValue->GetSize(), v8Value->GetIntValue()); + } else if (v8Value->IsUInt()) { + uint32 uint32_value = v8Value->GetUIntValue(); + CefRefPtr binaryValue = CefBinaryValue::Create( + &uint32_value, sizeof(uint32_value)); + listValue->SetBinary((int)listValue->GetSize(), binaryValue); + } else if (v8Value->IsDouble()) { + listValue->SetDouble((int)listValue->GetSize(), v8Value->GetDoubleValue()); + } else if (v8Value->IsDate()) { + // TODO: in time_utils.pyx there are already functions for + // converting cef_time_t to python DateTime, we could easily + // add a new function for converting the python DateTime to + // string and then to CefString and expose the function using + // the "public" keyword. But how do we get the cef_time_t + // structure from the CefTime class? GetDateValue() returns + // CefTime class. + listValue->SetNull((int)listValue->GetSize()); + } else if (v8Value->IsString()) { + listValue->SetString((int)listValue->GetSize(), v8Value->GetStringValue()); + } else if (v8Value->IsArray()) { + // Check for IsArray() must happen before the IsObject() check. + int length = v8Value->GetArrayLength(); + CefRefPtr newListValue = CefListValue::Create(); + for (int i = 0; i < length; ++i) { + V8ValueAppendToCefListValue(v8Value->GetValue(i), newListValue, + nestingLevel + 1); + } + listValue->SetList((int)listValue->GetSize(), newListValue); + } else if (v8Value->IsFunction()) { + // Check for IsFunction() must happen before the IsObject() check. + if (CefV8Context::InContext()) { + CefRefPtr context = \ + CefV8Context::GetCurrentContext(); + CefRefPtr frame = context->GetFrame(); + std::string strCallbackId = PutJavascriptCallback(frame, v8Value); + /* strCallbackId = '####cefpython####' \ + '{"what"=>"javascript-callback", ..}' */ + listValue->SetString((int)listValue->GetSize(), strCallbackId); + } else { + listValue->SetNull((int)listValue->GetSize()); + DebugLog("V8ValueAppendToCefListValue() FAILED: not in V8 context" + " , FATAL ERROR!"); + } + } else if (v8Value->IsObject()) { + // Check for IsObject() must happen after the IsArray() + // and IsFunction() checks. + listValue->SetDictionary((int)listValue->GetSize(), + V8ObjectToCefDictionaryValue(v8Value, nestingLevel + 1)); + } else { + listValue->SetNull((int)listValue->GetSize()); + DebugLog("V8ValueAppendToCefListValue() FAILED: unknown V8 type"); + } +} + +CefRefPtr V8ObjectToCefDictionaryValue( + CefRefPtr v8Object, + int nestingLevel) { + if (!v8Object->IsValid()) { + DebugLog("V8ObjectToCefDictionaryValue(): IsValid() FAILED"); + return CefDictionaryValue::Create(); + } + if (nestingLevel > 8) { + DebugLog("V8ObjectToCefDictionaryValue(): WARNING: " \ + "max nesting level (8) exceeded"); + return CefDictionaryValue::Create(); + } + if (!v8Object->IsObject()) { + DebugLog("V8ObjectToCefDictionaryValue(): IsObject() FAILED"); + return CefDictionaryValue::Create(); + } + CefRefPtr ret = CefDictionaryValue::Create(); + std::vector keys; + if (!v8Object->GetKeys(keys)) { + DebugLog("V8ObjectToCefDictionaryValue(): GetKeys() FAILED"); + return ret; + } + for (std::vector::iterator it = keys.begin(); \ + it != keys.end(); ++it) { + CefString key = *it; + CefRefPtr v8Value = v8Object->GetValue(key); + if (v8Value->IsUndefined() || v8Value->IsNull()) { + ret->SetNull(key); + } else if (v8Value->IsBool()) { + ret->SetBool(key, v8Value->GetBoolValue()); + } else if (v8Value->IsInt()) { + ret->SetInt(key, v8Value->GetIntValue()); + } else if (v8Value->IsUInt()) { + uint32 uint32_value = v8Value->GetUIntValue(); + CefRefPtr binaryValue = CefBinaryValue::Create( + &uint32_value, sizeof(uint32_value)); + ret->SetBinary(key, binaryValue); + } else if (v8Value->IsDouble()) { + ret->SetDouble(key, v8Value->GetDoubleValue()); + } else if (v8Value->IsDate()) { + // TODO: in time_utils.pyx there are already functions for + // converting cef_time_t to python DateTime, we could easily + // add a new function for converting the python DateTime to + // string and then to CefString and expose the function using + // the "public" keyword. But how do we get the cef_time_t + // structure from the CefTime class? GetDateValue() returns + // CefTime class. + ret->SetNull(key); + } else if (v8Value->IsString()) { + ret->SetString(key, v8Value->GetStringValue()); + } else if (v8Value->IsArray()) { + // Check for IsArray() must happen before the IsObject() check. + int length = v8Value->GetArrayLength(); + CefRefPtr newListValue = CefListValue::Create(); + for (int i = 0; i < length; ++i) { + V8ValueAppendToCefListValue(v8Value->GetValue(i), newListValue, + nestingLevel + 1); + } + ret->SetList(key, newListValue); + } else if (v8Value->IsFunction()) { + // Check for IsFunction() must happen before the IsObject() check. + if (CefV8Context::InContext()) { + CefRefPtr context = \ + CefV8Context::GetCurrentContext(); + CefRefPtr frame = context->GetFrame(); + std::string strCallbackId = PutJavascriptCallback( + frame, v8Value); + /* strCallbackId = '####cefpython####' \ + '{"what"=>"javascript-callback", ..}' */ + ret->SetString(key, strCallbackId); + } else { + ret->SetNull(key); + DebugLog("V8ObjectToCefDictionaryValue() FAILED: " \ + "not in V8 context FATAL ERROR!"); + } + } else if (v8Value->IsObject()) { + // Check for IsObject() must happen after the IsArray() + // and IsFunction() checks. + ret->SetDictionary(key, + V8ObjectToCefDictionaryValue(v8Value, nestingLevel + 1)); + } else { + ret->SetNull(key); + DebugLog("V8ObjectToCefDictionaryValue() FAILED: unknown V8 type"); + } + } + return ret; +} + +// ---------------------------------------------------------------------------- +// CEF values to V8 values. +// ---------------------------------------------------------------------------- + +// TODO: send callbackId using CefBinaryNamedValue, see: +// http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10881 +struct PythonCallback { + int callbackId; + char uniqueCefBinaryValueSize[16]; +}; + +template +inline std::string AnyToString(const T& value) +{ + std::ostringstream oss; + oss << value; + return oss.str(); +} + +CefV8ValueList CefListValueToCefV8ValueList( + CefRefPtr listValue) { + // CefV8ValueList = typedef std::vector > + CefV8ValueList v8ValueVector; + CefRefPtr v8List = CefListValueToV8Value(listValue); + int v8ListLength = v8List->GetArrayLength(); + for (int i = 0; i < v8ListLength; ++i) { + v8ValueVector.push_back(v8List->GetValue(i)); + } + return v8ValueVector; +} + +CefRefPtr CefListValueToV8Value( + CefRefPtr listValue, + int nestingLevel) { + if (!listValue->IsValid()) { + DebugLog("CefListValueToV8Value() FAILED: " \ + "CefDictionaryValue is invalid"); + return CefV8Value::CreateNull(); + } + if (nestingLevel > 8) { + DebugLog("CefListValueToV8Value(): WARNING: " \ + "max nesting level (8) exceeded"); + return CefV8Value::CreateNull(); + } + int listSize = (int)listValue->GetSize(); + CefRefPtr ret = CefV8Value::CreateArray(listSize); + CefRefPtr binaryValue; + PythonCallback pyCallback; + CefRefPtr v8FunctionHandler; + for (int key = 0; key < listSize; ++key) { + cef_value_type_t valueType = listValue->GetType(key); + bool success; + std::string callbackName = "python_callback_"; + if (valueType == VTYPE_NULL) { + success = ret->SetValue(key, + CefV8Value::CreateNull()); + } else if (valueType == VTYPE_BOOL) { + success = ret->SetValue(key, + CefV8Value::CreateBool(listValue->GetBool(key))); + } else if (valueType == VTYPE_INT) { + success = ret->SetValue(key, + CefV8Value::CreateInt(listValue->GetInt(key))); + } else if (valueType == VTYPE_DOUBLE) { + success = ret->SetValue(key, + CefV8Value::CreateDouble(listValue->GetDouble(key))); + } else if (valueType == VTYPE_STRING) { + success = ret->SetValue(key, + CefV8Value::CreateString(listValue->GetString(key))); + } else if (valueType == VTYPE_BINARY) { + binaryValue = listValue->GetBinary(key); + if (binaryValue->GetSize() == sizeof(pyCallback)) { + binaryValue->GetData(&pyCallback, sizeof(pyCallback), 0); + v8FunctionHandler = new V8FunctionHandler( + NULL, pyCallback.callbackId); + // You must provide a function name to + // CefV8Value::CreateFunction(), otherwise it fails. + callbackName.append(AnyToString(pyCallback.callbackId)); + success = ret->SetValue(key, + CefV8Value::CreateFunction( + callbackName, v8FunctionHandler)); + } else { + DebugLog("CefListValueToV8Value(): WARNING: " \ + "unknown binary value, setting value to null"); + success = ret->SetValue(key, CefV8Value::CreateNull()); + } + } else if (valueType == VTYPE_DICTIONARY) { + success = ret->SetValue(key, + CefDictionaryValueToV8Value( + listValue->GetDictionary(key), + nestingLevel + 1)); + } else if (valueType == VTYPE_LIST) { + success = ret->SetValue(key, + CefListValueToV8Value( + listValue->GetList(key), + nestingLevel + 1)); + } else { + DebugLog("CefListValueToV8Value(): WARNING: " \ + "unknown type, setting value to null"); + success = ret->SetValue(key, + CefV8Value::CreateNull()); + } + if (!success) { + DebugLog("CefListValueToV8Value(): WARNING: " \ + "ret->SetValue() failed"); + } + } + return ret; +} + +CefRefPtr CefDictionaryValueToV8Value( + CefRefPtr dictValue, + int nestingLevel) { + if (!dictValue->IsValid()) { + DebugLog("CefDictionaryValueToV8Value() FAILED: " \ + "CefDictionaryValue is invalid"); + return CefV8Value::CreateNull(); + } + if (nestingLevel > 8) { + DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ + "max nesting level (8) exceeded"); + return CefV8Value::CreateNull(); + } + std::vector keys; + if (!dictValue->GetKeys(keys)) { + DebugLog("CefDictionaryValueToV8Value() FAILED: " \ + "dictValue->GetKeys() failed"); + return CefV8Value::CreateNull(); + } + CefRefPtr ret = CefV8Value::CreateObject(NULL); + CefRefPtr binaryValue; + PythonCallback pyCallback; + CefRefPtr v8FunctionHandler; + for (std::vector::iterator it = keys.begin(); \ + it != keys.end(); ++it) { + CefString key = *it; + cef_value_type_t valueType = dictValue->GetType(key); + bool success; + std::string callbackName = "python_callback_"; + if (valueType == VTYPE_NULL) { + success = ret->SetValue(key, + CefV8Value::CreateNull(), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_BOOL) { + success = ret->SetValue(key, + CefV8Value::CreateBool(dictValue->GetBool(key)), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_INT) { + success = ret->SetValue(key, + CefV8Value::CreateInt(dictValue->GetInt(key)), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_DOUBLE) { + success = ret->SetValue(key, + CefV8Value::CreateDouble(dictValue->GetDouble(key)), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_STRING) { + success = ret->SetValue(key, + CefV8Value::CreateString(dictValue->GetString(key)), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_BINARY) { + binaryValue = dictValue->GetBinary(key); + if (binaryValue->GetSize() == sizeof(pyCallback)) { + binaryValue->GetData(&pyCallback, sizeof(pyCallback), 0); + v8FunctionHandler = new V8FunctionHandler( + NULL, pyCallback.callbackId); + // You must provide a function name to + // CefV8Value::CreateFunction(), otherwise it fails. + callbackName.append(AnyToString(pyCallback.callbackId)); + success = ret->SetValue(key, + CefV8Value::CreateFunction( + callbackName, v8FunctionHandler), + V8_PROPERTY_ATTRIBUTE_NONE); + } else { + DebugLog("CefListValueToV8Value(): WARNING: " \ + "unknown binary value, setting value to null"); + success = ret->SetValue(key, + CefV8Value::CreateNull(), + V8_PROPERTY_ATTRIBUTE_NONE); + } + } else if (valueType == VTYPE_DICTIONARY) { + success = ret->SetValue(key, + CefDictionaryValueToV8Value( + dictValue->GetDictionary(key), + nestingLevel + 1), + V8_PROPERTY_ATTRIBUTE_NONE); + } else if (valueType == VTYPE_LIST) { + success = ret->SetValue(key, + CefListValueToV8Value( + dictValue->GetList(key), + nestingLevel + 1), + V8_PROPERTY_ATTRIBUTE_NONE); + } else { + DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ + "unknown type, setting value to null"); + success = ret->SetValue(key, + CefV8Value::CreateNull(), + V8_PROPERTY_ATTRIBUTE_NONE); + } + if (!success) { + DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ + "ret->SetValue() failed"); + } + } + return ret; +} diff --git a/cefpython/cef3/subprocess/v8utils.h b/cefpython/cef3/subprocess/v8utils.h new file mode 100644 index 00000000..a6d0ed03 --- /dev/null +++ b/cefpython/cef3/subprocess/v8utils.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once +#include "include/cef_v8.h" +#include "include/cef_values.h" +#include "v8function_handler.h" + +// ---------------------------------------------------------------------------- +// V8 values to CEF values. +// ---------------------------------------------------------------------------- + +CefRefPtr V8ValueListToCefListValue( + const CefV8ValueList& v8List); + +void V8ValueAppendToCefListValue(const CefRefPtr v8Value, + CefRefPtr listValue, + int nestingLevel=0); + +CefRefPtr V8ObjectToCefDictionaryValue( + const CefRefPtr v8Object, + int nestingLevel=0); + +// ---------------------------------------------------------------------------- +// CEF values to V8 values. +// ---------------------------------------------------------------------------- + +CefV8ValueList CefListValueToCefV8ValueList( + CefRefPtr listValue); + +CefRefPtr CefListValueToV8Value( + CefRefPtr listValue, + int nestingLevel=0); + +CefRefPtr CefDictionaryValueToV8Value( + CefRefPtr dictValue, + int nestingLevel=0); diff --git a/cefpython/cef3/util.h b/cefpython/cef3/util.h new file mode 100644 index 00000000..ba0305c1 --- /dev/null +++ b/cefpython/cef3/util.h @@ -0,0 +1,37 @@ +// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEF_TESTS_CEFCLIENT_UTIL_H_ +#define CEF_TESTS_CEFCLIENT_UTIL_H_ +#pragma once + +#include "include/cef_task.h" + +#if defined(OS_WIN) + +#include // NOLINT(build/include_order) + +#ifndef NDEBUG +#define ASSERT(condition) if (!(condition)) { DebugBreak(); } +#else +#define ASSERT(condition) ((void)0) +#endif + +#else // !OS_WIN + +#include // NOLINT(build/include_order) + +#ifndef NDEBUG +#define ASSERT(condition) if (!(condition)) { assert(false); } +#else +#define ASSERT(condition) ((void)0) +#endif + +#endif // !OS_WIN + +#define REQUIRE_UI_THREAD() ASSERT(CefCurrentlyOn(TID_UI)); +#define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO)); +#define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE)); + +#endif // CEF_TESTS_CEFCLIENT_UTIL_H_ diff --git a/cefpython/cef3/windows/.gitignore b/cefpython/cef3/windows/.gitignore new file mode 100644 index 00000000..fb779dfc --- /dev/null +++ b/cefpython/cef3/windows/.gitignore @@ -0,0 +1,8 @@ +*.exe +*.dll +*.pak +*.lib + +!msvcr90.dll +!msvcp90.dll +!msvcm90.dll diff --git a/cefpython/cef3/windows/binaries_32bit/LICENSE.txt b/cefpython/cef3/windows/binaries_32bit/LICENSE.txt new file mode 100644 index 00000000..45e6f23e --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright (c) 2012 The CEF Python authors. All rights +reserved. Website: http://code.google.com/p/cefpython/ + +This product includes the following third party libraries: +* Chromium Embedded Framework licensed under the BSD 3-clause + license. Website: http://code.google.com/p/chromiumembedded/ + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef3/windows/binaries_32bit/README.txt b/cefpython/cef3/windows/binaries_32bit/README.txt new file mode 100644 index 00000000..73fbae0c --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/README.txt @@ -0,0 +1,119 @@ +Chromium Embedded Framework (CEF) Standard Binary Distribution for Windows +------------------------------------------------------------------------------- + +Date: August 08, 2014 + +CEF Version: 3.1650.1646 +CEF URL: http://chromiumembedded.googlecode.com/svn/branches/1650/cef3@1646 + +Chromium Verison: 31.0.1650.69 +Chromium URL: http://src.chromium.org/svn/branches/1650/src@241641 + +This distribution contains all components necessary to build and distribute an +application using CEF on the Windows platform. Please see the LICENSING +section of this document for licensing terms and conditions. + + +CONTENTS +-------- + +cefclient Contains the cefclient sample application configured to build + using the files in this distribution. + +Debug Contains libcef.dll, libcef.lib and other components required to + build and run the debug version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +include Contains all required CEF header files. + +libcef_dll Contains the source code for the libcef_dll_wrapper static library + that all applications using the CEF C++ API must link against. + +Release Contains libcef.dll, libcef.lib and other components required to + build and run the release version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +Resources Contains resources required by libcef.dll. By default these files + should be placed in the same directory as libcef.dll. By default + these files should be placed in the same directory as libcef.dll + and will be copied there as part of the build process. + + +USAGE +----- + +Visual Studio 2012 and Visual Studio 2010: + Open the cefclient2010.sln solution in Visual Studio and build. + +Visual Studio 2008: + Open the cefclient2008.sln solution in Visual Studio and build. + +Visual Studio 2005: + 1. Open the cefclient.vcproj and libcef_dll_wrapper.vcproj files in a text + editor. Change Version="9.00" to Version="8.00". + 2. Open the cefclient2005.sln file in a text editor. Change "Version 9.00" to + "Version 8.00". + 3. Open the cefclient2005.sln solution in Visual Studio and build. + +Please visit the CEF Website for additional usage information. + +http://code.google.com/p/chromiumembedded + + +REDISTRIBUTION +-------------- + +This binary distribution contains the below components. Components listed under +the "required" section must be redistributed with all applications using CEF. +Components listed under the "optional" section may be excluded if the related +features will not be used. + +Required components: + +* CEF core library + libcef.dll + +* Unicode support + icudt.dll + +Optional components: + +* Localized resources + locales/ + Note: Contains localized strings for WebKit UI controls. A .pak file is loaded + from this folder based on the CefSettings.locale value. Only configured + locales need to be distributed. If no locale is configured the default locale + of "en-US" will be used. Locale file loading can be disabled completely using + CefSettings.pack_loading_disabled. The locales folder path can be customized + using CefSettings.locales_dir_path. + +* Other resources + cef.pak + devtools_resources.pak + Note: Contains WebKit image and inspector resources. Pack file loading can be + disabled completely using CefSettings.pack_loading_disabled. The resources + directory path can be customized using CefSettings.resources_dir_path. + +* FFmpeg audio and video support + ffmpegsumo.dll + Note: Without this component HTML5 audio and video will not function. + +* Angle and Direct3D support + d3dcompiler_43.dll (required for Windows XP) + d3dcompiler_46.dll (required for Windows Vista and newer) + libEGL.dll + libGLESv2.dll + Note: Without these components HTML5 accelerated content like 2D canvas, 3D + CSS and WebGL will not function. + + +LICENSING +--------- + +The CEF project is BSD licensed. Please read the LICENSE.txt file included with +this binary distribution for licensing terms and conditions. Other software +included in this distribution is provided under other licenses. Please visit +"about:credits" in a CEF-based application for complete Chromium and third-party +licensing information. diff --git a/cefpython/cef3/windows/binaries_32bit/cefwindow.py b/cefpython/cef3/windows/binaries_32bit/cefwindow.py new file mode 100644 index 00000000..fd0ac73e --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/cefwindow.py @@ -0,0 +1,205 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +import win32gui +import win32con +import win32api +import time +import math +import os +import sys +import re + +if sys.version_info.major == 2: + from urllib import pathname2url as urllib_pathname2url +else: + from urllib.request import pathname2url as urllib_pathname2url + +g_debug = False +g_windows = {} # windowID(int): className +g_registeredClasses = {} + +def Debug(msg): + + if not g_debug: + return + msg = "cefwindow: "+str(msg) + print(msg) + with open(GetRealPath("debug.log"), "a") as file: + file.write(msg+"\n") + +def GetRealPath(file=None, encodeURL=False): + + # This function is defined in 2 files: cefpython.pyx and cefwindow.py, if you make changes edit both files. + # If file is None return current directory, without trailing slash. + + # encodeURL param - will call urllib.pathname2url(), only when file is empty (current dir) + # or is relative path ("test.html", "some/test.html"), we need to encode it before passing + # to CreateBrowser(), otherwise it is encoded by CEF internally and becomes (chinese characters): + # >> %EF%BF%97%EF%BF%80%EF%BF%83%EF%BF%A6 + # but should be: + # >> %E6%A1%8C%E9%9D%A2 + + if file is None: file = "" + if file.find("/") != 0 and file.find("\\") != 0 and not re.search(r"^[a-zA-Z]+:[/\\]?", file): + # Execute this block only when relative path ("test.html", "some\test.html") or file is empty (current dir). + # 1. find != 0 >> not starting with / or \ (/ - linux absolute path, \ - just to be sure) + # 2. not re.search >> not (D:\\ or D:/ or D: or http:// or ftp:// or file://), + # "D:" is also valid absolute path ("D:cefpython" in chrome becomes "file:///D:/cefpython/") + if hasattr(sys, "frozen"): path = os.path.dirname(sys.executable) + elif "__file__" in globals(): path = os.path.dirname(os.path.realpath(__file__)) + else: path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) # directory without trailing slash. + if encodeURL: + return urllib_pathname2url(path) + else: + return path + return file + +def CreateWindow(title, className, width, height, xpos=None, ypos=None, icon=None, windowProc=None): + + """ + for key in g_windows: + if g_windows[key] == className: + raise Exception("There was already created a window with that className: %s." + "Each created window must have an unique className." % className) + """ + + if not windowProc: + windowProc = {win32con.WM_CLOSE: WM_CLOSE} + + bigIcon = "" + smallIcon = "" + + if icon: + icon = GetRealPath(icon) + + # Load small and big icon. + # WNDCLASSEX (along with hIconSm) is not supported by pywin32, + # we need to use WM_SETICON message after window creation. + + # http://stackoverflow.com/questions/2234988/how-to-set-hicon-on-a-window-ico-with-multiple-sizes + # http://blog.barthe.ph/2009/07/17/wmseticon/ + + bigX = win32api.GetSystemMetrics(win32con.SM_CXICON) + bigY = win32api.GetSystemMetrics(win32con.SM_CYICON) + bigIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, bigX, bigY, win32con.LR_LOADFROMFILE) + smallX = win32api.GetSystemMetrics(win32con.SM_CXSMICON) + smallY = win32api.GetSystemMetrics(win32con.SM_CYSMICON) + smallIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, smallX, smallY, win32con.LR_LOADFROMFILE) + + wndclass = win32gui.WNDCLASS() + wndclass.hInstance = win32api.GetModuleHandle(None) + wndclass.lpszClassName = className + wndclass.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW + # win32con.CS_GLOBALCLASS + wndclass.hbrBackground = win32con.COLOR_WINDOW + wndclass.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) + wndclass.lpfnWndProc = windowProc + + #noinspection PyUnusedLocal + global g_registeredClasses + if not className in g_registeredClasses: + g_registeredClasses[className] = True + atomclass = win32gui.RegisterClass(wndclass) + Debug("win32gui.RegisterClass(%s)" % className) + + if xpos is None or ypos is None: + # Center window on the screen. + Debug("Centering window on the screen.") + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + + windowID = win32gui.CreateWindow(className, title, + win32con.WS_OVERLAPPEDWINDOW | win32con.WS_CLIPCHILDREN | win32con.WS_VISIBLE, + xpos, ypos, width, height, # xpos, ypos, width, height + 0, 0, wndclass.hInstance, None) + g_windows[windowID] = className + + if icon: + if bigIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_BIG, bigIcon) + if smallIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_SMALL, smallIcon) + + Debug("windowID = %s" % windowID) + return windowID + + +# Memory error when calling win32gui.DestroyWindow() +# after we called cefpython.CloseBrowser() + +def DestroyWindow(windowID): + + win32gui.DestroyWindow(windowID) + #className = GetWindowClassName(windowID) + #win32gui.UnregisterClass(className, None) + #del g_windows[windowID] # Let window with this className be created again. + + +def GetWindowClassName(windowID): + + for key in g_windows: + if key == windowID: + return g_windows[key] + +def MoveWindow(windowID, xpos=None, ypos=None, width=None, height=None, center=None): + + (left, top, right, bottom) = win32gui.GetWindowRect(windowID) + if xpos is None and ypos is None: + xpos = left + ypos = top + if width is None and height is None: + width = right - left + height = bottom - top + # Case: only ypos provided + if xpos is None and ypos is not None: + xpos = left + if ypos is None and xpos is not None: + ypos = top + # Case: only height provided + if not width: + width = right - left + if not height: + height = bottom - top + if center: + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + win32gui.MoveWindow(windowID, xpos, ypos, width, height, 1) + + +#noinspection PyUnusedLocal +def WM_CLOSE(windowID, msg, wparam, lparam): + + DestroyWindow(windowID) + win32gui.PostQuitMessage(0) + + +def GetLastError(): + + code = win32api.GetLastError() + return "(%d) %s" % (code, win32api.FormatMessage(code)) + +#noinspection PyUnusedLocal +def MessageLoop(className): + + while not win32gui.PumpWaitingMessages(): + time.sleep(0.001) + + +if __name__ == "__main__": + + g_debug = True + hwnd = CreateWindow("Test window", "testwindow", 800, 600) + MessageLoop("testwindow") \ No newline at end of file diff --git a/cefpython/cef3/windows/binaries_32bit/example.html b/cefpython/cef3/windows/binaries_32bit/example.html new file mode 100644 index 00000000..96bbac9b --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/example.html @@ -0,0 +1,58 @@ + + + + + CEF Python 3 example (utf-8: ąś) + + + + + + +

Use mouse context menu to go Back/Forward in history navigation.

+ + + +

Google Search

+https://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('example.html') + + + +

HTML5 video and accelerated content

+ +HTML 5 video
+ +Accelerated canvas
+ +Accelerated layers
+ + + +

Advanced example

+ +See the wxpython.py script for an advanced usage of CEF Python 3 +features - including javascript bindings, js and python callbacks, +client handlers and others. + + +



+



+



+



+ + + diff --git a/cefpython/cef3/windows/binaries_32bit/icon.ico b/cefpython/cef3/windows/binaries_32bit/icon.ico new file mode 100644 index 00000000..435045ae Binary files /dev/null and b/cefpython/cef3/windows/binaries_32bit/icon.ico differ diff --git a/cefpython/cef3/windows/binaries_32bit/prism.css b/cefpython/cef3/windows/binaries_32bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/windows/binaries_32bit/prism.js b/cefpython/cef3/windows/binaries_32bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/windows/binaries_32bit/pygtk_.py b/cefpython/cef3/windows/binaries_32bit/pygtk_.py new file mode 100644 index 00000000..8c143783 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/pygtk_.py @@ -0,0 +1,197 @@ +# An example of embedding CEF browser in PyGTK on Windows. +# Tested with PyGTK 2.24.10 + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pygtk_.py]: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + + def __init__(self): + gobject.timeout_add(10, self.OnTimer) + + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=1024, height=768) + self.mainWindow.set_title('PyGTK CEF 3 example') + self.mainWindow.realize() + + self.container = gtk.DrawingArea() + self.container.set_property('can-focus', True) + self.container.connect('size-allocate', self.OnSize) + self.container.show() + + self.searchEntry = gtk.Entry() + # By default, clicking a GTK widget doesn't grab the focus away from a native Win32 control (browser). + self.searchEntry.connect('button-press-event', self.OnWidgetClick) + self.searchEntry.show() + + table = gtk.Table(3, 1, homogeneous=False) + self.mainWindow.add(table) + table.attach(self.CreateMenu(), 0, 1, 0, 1, yoptions=gtk.SHRINK) + table.attach(self.searchEntry, 0, 1, 1, 2, yoptions=gtk.SHRINK) + table.attach(self.container, 0, 1, 2, 3) + table.show() + + windowID = self.container.get_window().handle + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath('example.html')) + + self.mainWindow.show() + + # Browser took focus, we need to get it back and give to searchEntry. + self.mainWindow.get_window().focus() + self.searchEntry.grab_focus() + + def CreateMenu(self): + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + about = gtk.MenuItem('About') + about.show() + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + return menubar + + def OnWidgetClick(self, widget, data): + self.mainWindow.get_window().focus() + + def OnTimer(self): + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + # This function is currently not called by any of code, but if you would like + # for browser to have automatic focus add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + cefpython.WindowUtils.OnSetFocus(self.container.get_window().handle, 0, 0, 0) + + def OnSize(self, widget, sizeAlloc): + cefpython.WindowUtils.OnSize(self.container.get_window().handle, 0, 0, 0) + + def OnExit(self, widget, data=None): + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + version = '.'.join(map(str, list(gtk.gtk_version))) + print('[pygtk_.py] GTK version: %s' % version) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable + "release_dcheck_enabled": True, # Enable only when debugging + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + cefpython.Initialize(settings) + + gobject.threads_init() # Timer for the message loop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_32bit/pyqt.py b/cefpython/cef3/windows/binaries_32bit/pyqt.py new file mode 100644 index 00000000..6c042261 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/pyqt.py @@ -0,0 +1,191 @@ +# An example of embedding CEF browser in a PyQt4 application. +# Tested with PyQt 4.10.3 (Qt 4.8.5). + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +from PyQt4 import QtGui +from PyQt4 import QtCore + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pyqt.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PyQT CEF 3 example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winId()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winId())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("example.html")) + self.show() + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("[pyqt.py] PyQt version: %s" % QtCore.PYQT_VERSION_STR) + print("[pyqt.py] QtCore version: %s" % QtCore.qVersion()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + # "cache_path": "webcache/", # Disk cache + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "enable-media-stream": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_32bit/pyside.py b/cefpython/cef3/windows/binaries_32bit/pyside.py new file mode 100644 index 00000000..9e48cbf8 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/pyside.py @@ -0,0 +1,189 @@ +# An example of embedding CEF Python in PySide application. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import PySide +from PySide import QtGui +from PySide import QtCore +import ctypes + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PySide example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winIdFixed()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winIdFixed())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("example.html")) + self.show() + + def winIdFixed(self): + # PySide bug: QWidget.winId() returns , + # there is no easy way to convert it to int. + try: + return int(self.winId()) + except: + if sys.version_info[0] == 2: + ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p + ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCObject_AsVoidPtr(self.winId()) + elif sys.version_info[0] == 3: + ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p + ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCapsule_GetPointer(self.winId(), None) + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("PySide version: %s" % PySide.__version__) + print("QtCore version: %s" % QtCore.__version__) + + sys.excepthook = ExceptHook + settings = {} + settings["log_file"] = GetApplicationPath("debug.log") + settings["log_severity"] = cefpython.LOGSEVERITY_INFO + settings["release_dcheck_enabled"] = True # Enable only when debugging + settings["browser_subprocess_path"] = "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + cefpython.Initialize(settings) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_32bit/pywin32.py b/cefpython/cef3/windows/binaries_32bit/pywin32.py new file mode 100644 index 00000000..0d87e346 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/pywin32.py @@ -0,0 +1,152 @@ +# Example of embedding CEF browser using the PyWin32 extension. +# Tested with pywin32 version 218. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import cefwindow +import win32con +import win32gui +import win32api +import time + +DEBUG = True + +# ----------------------------------------------------------------------------- +# Helper functions. + +def Log(msg): + print("[pywin32.py] %s" % str(msg)) + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pywin32.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +# ----------------------------------------------------------------------------- + +def CefAdvanced(): + sys.excepthook = ExceptHook + + appSettings = dict() + # appSettings["cache_path"] = "webcache/" # Disk cache + if DEBUG: + # cefpython debug messages in console and in log_file + appSettings["debug"] = True + cefwindow.g_debug = True + appSettings["log_file"] = GetApplicationPath("debug.log") + appSettings["log_severity"] = cefpython.LOGSEVERITY_INFO + appSettings["release_dcheck_enabled"] = True # Enable only when debugging + appSettings["browser_subprocess_path"] = "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + cefpython.Initialize(appSettings) + + wndproc = { + win32con.WM_CLOSE: CloseWindow, + win32con.WM_DESTROY: QuitApplication, + win32con.WM_SIZE: cefpython.WindowUtils.OnSize, + win32con.WM_SETFOCUS: cefpython.WindowUtils.OnSetFocus, + win32con.WM_ERASEBKGND: cefpython.WindowUtils.OnEraseBackground + } + + browserSettings = dict() + browserSettings["universal_access_from_file_urls_allowed"] = True + browserSettings["file_access_from_file_urls_allowed"] = True + + if os.path.exists("icon.ico"): + icon = os.path.abspath("icon.ico") + else: + icon = "" + + windowHandle = cefwindow.CreateWindow(title="pywin32 example", + className="cefpython3_example", width=1024, height=768, + icon=icon, windowProc=wndproc) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowHandle) + browser = cefpython.CreateBrowserSync(windowInfo, browserSettings, + navigateUrl=GetApplicationPath("example.html")) + cefpython.MessageLoop() + cefpython.Shutdown() + +def CloseWindow(windowHandle, message, wparam, lparam): + browser = cefpython.GetBrowserByWindowHandle(windowHandle) + browser.CloseBrowser() + return win32gui.DefWindowProc(windowHandle, message, wparam, lparam) + +def QuitApplication(windowHandle, message, wparam, lparam): + win32gui.PostQuitMessage(0) + return 0 + +def GetPywin32Version(): + fixed_file_info = win32api.GetFileVersionInfo(win32api.__file__, '\\') + return fixed_file_info['FileVersionLS'] >> 16 + +if __name__ == "__main__": + Log("pywin32 version = %s" % GetPywin32Version()) + CefAdvanced() diff --git a/cefpython/cef3/windows/binaries_32bit/smoke.css b/cefpython/cef3/windows/binaries_32bit/smoke.css new file mode 100644 index 00000000..2936c818 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/smoke.css @@ -0,0 +1,110 @@ +.smoke-base { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + visibility: hidden; + opacity: 0; +} + +.smoke-base.smoke-visible { + opacity: 1; + visibility: visible; +} + +.smokebg { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.smoke-base .dialog { + position: absolute; +} + +.dialog-prompt { + margin-top: 15px; + text-align: center; +} + +.dialog-buttons { + margin: 20px 0 5px 0 +} + +.smoke { +} + +.dialog-buttons button { + display: inline-block; + vertical-align: baseline; + cursor: pointer; + font-family: Menlo, 'Andale Mono', monospace; + font-style: normal; + text-decoration: none; + border: 0; + outline: 0; + margin: 0 5px; + -webkit-background-clip: padding-box; + font-size: 13px; + line-height: 13px; + font-weight: normal; + padding: 9px 12px; +} + +.dialog-prompt input { + margin: 0; + border: 0; + font-family: sans-serif; + outline: none; + font-family: Menlo, 'Andale Mono', monospace; + border: 1px solid #aaa; + width: 75%; + display: inline-block; + background-color: transparent; + font-size: 16px; + padding: 8px; +} + +.smoke-base { + background: rgba(0,0,0,.3); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#90000000,endColorstr=#900000000); +} + +.smoke-base .dialog { + top: 25%; + width: 40%; + left: 50%; + margin-left: -20%; +} + +.smoke-base .dialog-inner { + padding: 15px; + + color:#202020; +} + +.smoke { + background-color: rgba(255,255,255,0.95); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff,endColorstr=#ffffff); + box-shadow: 0 2px 8px #666; +} + + +.dialog-buttons button { + background-color: rgba(0,0,0,.85); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#222222,endColorstr=#222222); + border-radius: 0; + color: #fff; +} + +button.cancel { + background-color: rgba(0,0,0,.40); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#444444,endColorstr=#444444); +} + +.queue{ + display:none; +} diff --git a/cefpython/cef3/windows/binaries_32bit/smoke.min.js b/cefpython/cef3/windows/binaries_32bit/smoke.min.js new file mode 100644 index 00000000..61fb4f0c --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/smoke.min.js @@ -0,0 +1 @@ +(function(e,t){var n={smoketimeout:[],init:false,zindex:1e3,i:0,bodyload:function(e){var r=t.createElement("div");r.setAttribute("id","smoke-out-"+e);r.className="smoke-base";r.style.zIndex=n.zindex;n.zindex++;t.body.appendChild(r)},newdialog:function(){var t=(new Date).getTime();t=Math.random(1,99)+t;if(!n.init){n.listen(e,"load",function(){n.bodyload(t)})}else{n.bodyload(t)}return t},forceload:function(){},build:function(t,r){n.i++;r.stack=n.i;t=t.replace(/\n/g,"
");t=t.replace(/\r/g,"
");var i="",s="OK",o="Cancel",u="",a="",f;if(r.type==="prompt"){i='
'+'"+"
"}if(r.params.ok){s=r.params.ok}if(r.params.cancel){o=r.params.cancel}if(r.params.classname){u=r.params.classname}if(r.type!=="signal"){a='
';if(r.type==="alert"){a+='"}else if(r.type==="quiz"){if(r.params.button_1){a+='"}if(r.params.button_2){a+='"}if(r.params.button_3){a+='"}if(r.params.button_cancel){a+='"}}else if(r.type==="prompt"||r.type==="confirm"){if(r.params.reverseButtons){a+='"+'"}else{a+='"+'"}}a+="
"}f='
'+'
'+'
'+t+i+a+"
"+"
";if(!n.init){n.listen(e,"load",function(){n.finishbuild(t,r,f)})}else{n.finishbuild(t,r,f)}},finishbuild:function(e,r,i){var s=t.getElementById("smoke-out-"+r.newid);s.className="smoke-base smoke-visible smoke-"+r.type;s.innerHTML=i;while(s.innerHTML===""){s.innerHTML=i}if(n.smoketimeout[r.newid]){clearTimeout(n.smoketimeout[r.newid])}n.listen(t.getElementById("smoke-bg-"+r.newid),"click",function(){n.destroy(r.type,r.newid);if(r.type==="prompt"||r.type==="confirm"||r.type==="quiz"){r.callback(false)}else if(r.type==="alert"&&typeof r.callback!=="undefined"){r.callback()}});switch(r.type){case"alert":n.finishbuildAlert(e,r,i);break;case"confirm":n.finishbuildConfirm(e,r,i);break;case"quiz":n.finishbuildQuiz(e,r,i);break;case"prompt":n.finishbuildPrompt(e,r,i);break;case"signal":n.finishbuildSignal(e,r,i);break;default:throw"Unknown type: "+r.type}},finishbuildAlert:function(r,i,s){n.listen(t.getElementById("alert-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13||t.keyCode===32||t.keyCode===27){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}}}},finishbuildConfirm:function(r,i,s){n.listen(t.getElementById("confirm-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});n.listen(t.getElementById("confirm-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(true)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13||t.keyCode===32){n.destroy(i.type,i.newid);i.callback(true)}else if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildQuiz:function(r,i,s){var o,u,a;n.listen(t.getElementById("quiz-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});if(o=t.getElementById("quiz-ok1-"+i.newid))n.listen(o,"click",function(){n.destroy(i.type,i.newid);i.callback(o.innerHTML)});if(u=t.getElementById("quiz-ok2-"+i.newid))n.listen(u,"click",function(){n.destroy(i.type,i.newid);i.callback(u.innerHTML)});if(a=t.getElementById("quiz-ok3-"+i.newid))n.listen(a,"click",function(){n.destroy(i.type,i.newid);i.callback(a.innerHTML)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildPrompt:function(r,i,s){var o=t.getElementById("dialog-input-"+i.newid);setTimeout(function(){o.focus();o.select()},100);n.listen(t.getElementById("prompt-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});n.listen(t.getElementById("prompt-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(o.value)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13){n.destroy(i.type,i.newid);i.callback(o.value)}else if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildSignal:function(r,i,s){t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===27){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}}};n.smoketimeout[i.newid]=setTimeout(function(){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}},i.timeout)},destroy:function(e,r){var i=t.getElementById("smoke-out-"+r);if(e!=="quiz"){var s=t.getElementById(e+"-ok-"+r)}var o=t.getElementById(e+"-cancel-"+r);i.className="smoke-base";if(s){n.stoplistening(s,"click",function(){});t.onkeyup=null}if(e==="quiz"){var u=t.getElementsByClassName("quiz-button");for(var a=0;a + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + + + + +Use the mouse context menu to go Back/Forward in history navigation. + +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
  5. + window.open('https://www.google.com/') +
  6. +
+ +There are problems with keyboard in wxPython when popup windows are created +by CEF ( +Issue 80). To create the popup window of our own, the +LifespanHandler::OnBeforePopup callback was implemented. Note that this has +its implications, the popup window and parent window will not be able to +script each other. There will be no "window.opener" property available +in the popup window. + +See its source: + + + + +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key which is handled in KeyboardHandler.OnKeyEvent
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

SetZoomLevel

+(You must set ApplicationSettings.auto_zooming = "" for SetZoomLevel calls +to work)
+external.SetZoomLevel(2.0)
+external.SetZoomLevel(1.0) + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python', 0, [1,2]) +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ + +Try magnet link to download a torrent: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu +to return back here after visiting that url:
+ + https://testssl-expire.disig.sk/index.en.html +
+ +This url will be allowed:
+ + https://testssl-expire.disig.sk/index.en.html?allow=1 +
+After you've clicked the second url, the first one will now be allowed, +as this is the same domain and it's cached now. + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
  2. +
  3. Open cookietester in a popup - a separate cookie manager is used:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie on html-kit.com: +external.SetCookie() +
+Go see the cookie that was created: + + http://www.html-kit.com/tools/cookietester/ + +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+Go check if cookie was deleted: + + http://www.html-kit.com/tools/cookietester/ + + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +After you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. +
+Try this: + + http://www.non-existent.nono/ +
+ + + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + window.alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/windows/binaries_32bit/wxpython.py b/cefpython/cef3/windows/binaries_32bit/wxpython.py new file mode 100644 index 00000000..ed12af69 --- /dev/null +++ b/cefpython/cef3/windows/binaries_32bit/wxpython.py @@ -0,0 +1,910 @@ +# An example of embedding CEF browser in wxPython on Windows. +# Tested with wxPython 2.8.12.1 and 3.0.2.0. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect +import struct + +# ----------------------------------------------------------------------------- +# Globals + +g_applicationSettings = None +g_browserSettings = None +g_commandLineSwitches = None + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority +# EVT_TIMER - cef browser has priority (default) +# It seems that Flash content behaves better when using a timer. +# Not sure if using EVT_IDLE is correct, it doesn't work on Linux, +# on Windows it works fine. See also the post by Robin Dunn: +# https://groups.google.com/d/msg/wxpython-users/hcNdMEx8u48/MD5Jgbm_k1kJ +USE_EVT_IDLE = False # If False then Timer will be used + +TEST_EMBEDDING_IN_PANEL = True + +# ----------------------------------------------------------------------------- + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def GetHandleForBrowser(self): + if self.mainPanel: + return self.mainPanel.GetHandle() + else: + return self.GetHandle() + + def __init__(self, url=None, popup=False): + if popup: + title = "wxPython Popup" + else: + title = "wxPython CEF 3 example" + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title=title) + size=(800,600) + + # This is an optional code to enable High DPI support. + if "auto_zooming" in g_applicationSettings \ + and g_applicationSettings["auto_zooming"] == "system_dpi": + # This utility function will adjust width/height using + # OS DPI settings. For 800/600 with Win7 DPI settings + # being set to "Larger 150%" will return 1200/900. + size = cefpython.DpiAware.CalculateWindowSize(size[0], size[1]) + + self.SetSize(size) + + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + if TEST_EMBEDDING_IN_PANEL: + print("Embedding in a wx.Panel!") + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + self.clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + self.clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + self.clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + self.clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.GetHandleForBrowser()) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings=g_browserSettings, + navigateUrl=url) + + self.clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(self.clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + self.javascriptExternal = JavascriptExternal(self.browser) + jsBindings.SetObject("external", self.javascriptExternal) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + if self.mainPanel: + self.mainPanel.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.mainPanel.Bind(wx.EVT_SIZE, self.OnSize) + else: + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE and not popup: + # Bind EVT_IDLE only for the main application frame. + print("Using EVT_IDLE to execute the CEF message loop work") + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnSetFocus(self, event): + cefpython.WindowUtils.OnSetFocus(self.GetHandleForBrowser(), 0, 0, 0) + + def OnSize(self, event): + cefpython.WindowUtils.OnSize(self.GetHandleForBrowser(), 0, 0, 0) + + def OnClose(self, event): + # Remove all CEF browser references so that browser is closed + # cleanly. Otherwise there may be issues for example with cookies + # not being flushed to disk when closing app immediately + # (Issue 158). + del self.javascriptExternal.mainBrowser + del self.clientHandler.mainBrowser + del self.browser + + # Destroy wx frame, this will complete the destruction of CEF browser + self.Destroy() + + # In wx.chromectrl calling browser.CloseBrowser and/or self.Destroy + # may cause crashes when embedding multiple browsers in tab + # (Issue 107). In such case instead of calling CloseBrowser/Destroy + # try this code: + # | self.browser.ParentWindowWillClose() + # | event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def SetZoomLevel(self, zoomLevel): + self.mainBrowser.SetZoomLevel(zoomLevel) + + def CreateAnotherBrowser(self, url=None): + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s" \ + % event["focus_on_editable_field"]) + linux = (platform.system() == "Linux") + windows = (platform.system() == "Windows") + # F5 + if (linux and event["native_key_code"] == 71) \ + or (windows and event["windows_key_code"] == 116): + print("[wxpython.py] F5 pressed, calling" + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if (linux and event["native_key_code"] == 9) \ + or (windows and event["windows_key_code"] == 27): + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if (linux and event["native_key_code"] == 96) \ + or (windows and event["windows_key_code"] == 123): + print("[wxpython.py] F12 pressed, calling" + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + # Handle "magnet:" links. + if request.GetUrl().startswith("magnet:"): + print("[wxpython.p] RequestHandler::OnBeforeBrowse(): " + "magnet link clicked, cancelling browse request") + return True + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + if "cache_path" in g_applicationSettings: + path = g_applicationSettings["cache_path"] + # path = os.path.join(path, "cookies_browser_{}".format( + # browser.GetIdentifier())) + cookieManager.SetStoragePath(path) + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl == "https://testssl-expire.disig.sk/index.en.html": + print(" Not allowed!") + return False + if requestUrl \ + == "https://testssl-expire.disig.sk/index.en.html?allow=1": + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + # 3. Certificate error + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load " + "error: Esc was pressed or file download was aborted, " + "or there was certificate error") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName, + popupFeatures, windowInfo, client, browserSettings, + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + + # On Windows there are keyboard problems in popups, when popup + # is created using "window.open" or "target=blank". This issue + # occurs only in wxPython. PyGTK or PyQt do not require this fix. + # The solution is to create window explicitilly, and not depend + # on CEF to create window internally. See Issue 80 for details: + # https://code.google.com/p/cefpython/issues/detail?id=80 + + # If you set allowPopups=True then CEF will create popup window. + # The wx.Frame cannot be created here, as this callback is + # executed on the IO thread. Window should be created on the UI + # thread. One solution is to call cefpython.CreateBrowser() + # which runs asynchronously and can be called on any thread. + # The other solution is to post a task on the UI thread, so + # that cefpython.CreateBrowserSync() can be used. + + # Note that if you return True and create the popup window yourself, + # then the popup window and parent window will not be able to script + # each other. There will be no "window.opener" property available + # in the popup window. + + cefpython.PostTask(cefpython.TID_UI, self._CreatePopup, targetUrl) + + allowPopups = False + return not allowPopups + + def _CreatePopup(self, url): + frame = MainFrame(url=url, popup=True) + frame.Show() + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + mainFrame = None + + def OnInit(self): + if not USE_EVT_IDLE: + print("[wxpython.py] Using TIMER to run CEF message loop") + self.CreateTimer() + self.mainFrame = MainFrame() + self.SetTopWindow(self.mainFrame) + self.mainFrame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + print("[wxpython.py] MyApp.OnExit") + if not USE_EVT_IDLE: + self.timer.Stop() + + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + + +if __name__ == '__main__': + print('[wxpython.py] architecture=%s-bit' % (8 * struct.calcsize("P"))) + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + g_applicationSettings = { + # Disk cache + # "cache_path": "webcache/", + + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + + # These directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + + "downloads_enabled": True, + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": True, + } + + # You can comment out the code below if you do not want High + # DPI support. If you disable it text will look fuzzy on + # high DPI displays. + # + # Enabling High DPI support in app can be done by + # embedding a DPI awareness xml manifest in executable + # (see Issue 112 comment #2), or by calling SetProcessDpiAware + # function. Embedding xml manifest is the most reliable method. + # The downside of calling SetProcessDpiAware is that scrollbar + # in CEF browser is smaller than it should be. This is because + # DPI awareness was set too late, after the CEF dll was loaded. + # To fix that embed DPI awareness xml manifest in the .exe file. + # + # There is one bug when enabling High DPI support - fonts in + # javascript dialogs (alert) are tiny. However, you can implement + # custom javascript dialogs using JavascriptDialogHandler. + # + # Additionally you have to set "auto_zomming" application + # setting. High DPI support is available only on Windows. + # You may set auto_zooming to "system_dpi" and browser + # contents will be zoomed using OS DPI settings. On Win7 + # these can be set in: Control Panel > Appearance and + # Personalization > Display. + # + # Example values for auto_zooming are: + # "system_dpi", "0.0" (96 DPI), "1.0" (120 DPI), + # "2.0" (144 DPI), "-1.0" (72 DPI) + # Numeric value means a zoom level. + # Example values that can be set in Win7 DPI settings: + # Smaller 100% (Default) = 96 DPI = 0.0 zoom level + # Medium 125% = 120 DPI = 1.0 zoom level + # Larger 150% = 144 DPI = 2.0 zoom level + # Custom 75% = 72 DPI = -1.0 zoom level + g_applicationSettings["auto_zooming"] = "system_dpi" + print("[wxpython.py] Calling SetProcessDpiAware") + cefpython.DpiAware.SetProcessDpiAware() + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + g_commandLineSwitches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "disable-gpu": "", + + } + + cefpython.Initialize(g_applicationSettings, g_commandLineSwitches) + + app = MyApp(False) + app.MainLoop() + + # Let wx.App destructor do the cleanup before calling + # cefpython.Shutdown(). This is to ensure reliable CEF shutdown. + del app + + cefpython.Shutdown() + diff --git a/cefpython/cef3/windows/binaries_64bit/LICENSE.txt b/cefpython/cef3/windows/binaries_64bit/LICENSE.txt new file mode 100644 index 00000000..45e6f23e --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/LICENSE.txt @@ -0,0 +1,39 @@ +Copyright (c) 2012 The CEF Python authors. All rights +reserved. Website: http://code.google.com/p/cefpython/ + +This product includes the following third party libraries: +* Chromium Embedded Framework licensed under the BSD 3-clause + license. Website: http://code.google.com/p/chromiumembedded/ + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Google Inc. nor the name Chromium + Embedded Framework nor the name of CEF Python nor the + names of its contributors may be used to endorse or + promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cefpython/cef3/windows/binaries_64bit/README.txt b/cefpython/cef3/windows/binaries_64bit/README.txt new file mode 100644 index 00000000..3158cb80 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/README.txt @@ -0,0 +1,119 @@ +Chromium Embedded Framework (CEF) Standard Binary Distribution for Windows +------------------------------------------------------------------------------- + +Date: March 14, 2014 + +CEF Version: 3.1650.1639 +CEF URL: http://chromiumembedded.googlecode.com/svn/branches/1650/cef3@1639 + +Chromium Verison: 31.0.1650.57 +Chromium URL: http://src.chromium.org/svn/branches/1650/src@235101 + +This distribution contains all components necessary to build and distribute an +application using CEF on the Windows platform. Please see the LICENSING +section of this document for licensing terms and conditions. + + +CONTENTS +-------- + +cefclient Contains the cefclient sample application configured to build + using the files in this distribution. + +Debug Contains libcef.dll, libcef.lib and other components required to + build and run the debug version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +include Contains all required CEF header files. + +libcef_dll Contains the source code for the libcef_dll_wrapper static library + that all applications using the CEF C++ API must link against. + +Release Contains libcef.dll, libcef.lib and other components required to + build and run the release version of CEF-based applications. By + default these files should be placed in the same directory as the + executable and will be copied there as part of the build process. + +Resources Contains resources required by libcef.dll. By default these files + should be placed in the same directory as libcef.dll. By default + these files should be placed in the same directory as libcef.dll + and will be copied there as part of the build process. + + +USAGE +----- + +Visual Studio 2012 and Visual Studio 2010: + Open the cefclient2010.sln solution in Visual Studio and build. + +Visual Studio 2008: + Open the cefclient2008.sln solution in Visual Studio and build. + +Visual Studio 2005: + 1. Open the cefclient.vcproj and libcef_dll_wrapper.vcproj files in a text + editor. Change Version="9.00" to Version="8.00". + 2. Open the cefclient2005.sln file in a text editor. Change "Version 9.00" to + "Version 8.00". + 3. Open the cefclient2005.sln solution in Visual Studio and build. + +Please visit the CEF Website for additional usage information. + +http://code.google.com/p/chromiumembedded + + +REDISTRIBUTION +-------------- + +This binary distribution contains the below components. Components listed under +the "required" section must be redistributed with all applications using CEF. +Components listed under the "optional" section may be excluded if the related +features will not be used. + +Required components: + +* CEF core library + libcef.dll + +* Unicode support + icudt.dll + +Optional components: + +* Localized resources + locales/ + Note: Contains localized strings for WebKit UI controls. A .pak file is loaded + from this folder based on the CefSettings.locale value. Only configured + locales need to be distributed. If no locale is configured the default locale + of "en-US" will be used. Locale file loading can be disabled completely using + CefSettings.pack_loading_disabled. The locales folder path can be customized + using CefSettings.locales_dir_path. + +* Other resources + cef.pak + devtools_resources.pak + Note: Contains WebKit image and inspector resources. Pack file loading can be + disabled completely using CefSettings.pack_loading_disabled. The resources + directory path can be customized using CefSettings.resources_dir_path. + +* FFmpeg audio and video support + ffmpegsumo.dll + Note: Without this component HTML5 audio and video will not function. + +* Angle and Direct3D support + d3dcompiler_43.dll (required for Windows XP) + d3dcompiler_46.dll (required for Windows Vista and newer) + libEGL.dll + libGLESv2.dll + Note: Without these components HTML5 accelerated content like 2D canvas, 3D + CSS and WebGL will not function. + + +LICENSING +--------- + +The CEF project is BSD licensed. Please read the LICENSE.txt file included with +this binary distribution for licensing terms and conditions. Other software +included in this distribution is provided under other licenses. Please visit +"about:credits" in a CEF-based application for complete Chromium and third-party +licensing information. diff --git a/cefpython/cef3/windows/binaries_64bit/cefwindow.py b/cefpython/cef3/windows/binaries_64bit/cefwindow.py new file mode 100644 index 00000000..fd0ac73e --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/cefwindow.py @@ -0,0 +1,205 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +import win32gui +import win32con +import win32api +import time +import math +import os +import sys +import re + +if sys.version_info.major == 2: + from urllib import pathname2url as urllib_pathname2url +else: + from urllib.request import pathname2url as urllib_pathname2url + +g_debug = False +g_windows = {} # windowID(int): className +g_registeredClasses = {} + +def Debug(msg): + + if not g_debug: + return + msg = "cefwindow: "+str(msg) + print(msg) + with open(GetRealPath("debug.log"), "a") as file: + file.write(msg+"\n") + +def GetRealPath(file=None, encodeURL=False): + + # This function is defined in 2 files: cefpython.pyx and cefwindow.py, if you make changes edit both files. + # If file is None return current directory, without trailing slash. + + # encodeURL param - will call urllib.pathname2url(), only when file is empty (current dir) + # or is relative path ("test.html", "some/test.html"), we need to encode it before passing + # to CreateBrowser(), otherwise it is encoded by CEF internally and becomes (chinese characters): + # >> %EF%BF%97%EF%BF%80%EF%BF%83%EF%BF%A6 + # but should be: + # >> %E6%A1%8C%E9%9D%A2 + + if file is None: file = "" + if file.find("/") != 0 and file.find("\\") != 0 and not re.search(r"^[a-zA-Z]+:[/\\]?", file): + # Execute this block only when relative path ("test.html", "some\test.html") or file is empty (current dir). + # 1. find != 0 >> not starting with / or \ (/ - linux absolute path, \ - just to be sure) + # 2. not re.search >> not (D:\\ or D:/ or D: or http:// or ftp:// or file://), + # "D:" is also valid absolute path ("D:cefpython" in chrome becomes "file:///D:/cefpython/") + if hasattr(sys, "frozen"): path = os.path.dirname(sys.executable) + elif "__file__" in globals(): path = os.path.dirname(os.path.realpath(__file__)) + else: path = os.getcwd() + path = path + os.sep + file + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) # directory without trailing slash. + if encodeURL: + return urllib_pathname2url(path) + else: + return path + return file + +def CreateWindow(title, className, width, height, xpos=None, ypos=None, icon=None, windowProc=None): + + """ + for key in g_windows: + if g_windows[key] == className: + raise Exception("There was already created a window with that className: %s." + "Each created window must have an unique className." % className) + """ + + if not windowProc: + windowProc = {win32con.WM_CLOSE: WM_CLOSE} + + bigIcon = "" + smallIcon = "" + + if icon: + icon = GetRealPath(icon) + + # Load small and big icon. + # WNDCLASSEX (along with hIconSm) is not supported by pywin32, + # we need to use WM_SETICON message after window creation. + + # http://stackoverflow.com/questions/2234988/how-to-set-hicon-on-a-window-ico-with-multiple-sizes + # http://blog.barthe.ph/2009/07/17/wmseticon/ + + bigX = win32api.GetSystemMetrics(win32con.SM_CXICON) + bigY = win32api.GetSystemMetrics(win32con.SM_CYICON) + bigIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, bigX, bigY, win32con.LR_LOADFROMFILE) + smallX = win32api.GetSystemMetrics(win32con.SM_CXSMICON) + smallY = win32api.GetSystemMetrics(win32con.SM_CYSMICON) + smallIcon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, smallX, smallY, win32con.LR_LOADFROMFILE) + + wndclass = win32gui.WNDCLASS() + wndclass.hInstance = win32api.GetModuleHandle(None) + wndclass.lpszClassName = className + wndclass.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW + # win32con.CS_GLOBALCLASS + wndclass.hbrBackground = win32con.COLOR_WINDOW + wndclass.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) + wndclass.lpfnWndProc = windowProc + + #noinspection PyUnusedLocal + global g_registeredClasses + if not className in g_registeredClasses: + g_registeredClasses[className] = True + atomclass = win32gui.RegisterClass(wndclass) + Debug("win32gui.RegisterClass(%s)" % className) + + if xpos is None or ypos is None: + # Center window on the screen. + Debug("Centering window on the screen.") + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + + windowID = win32gui.CreateWindow(className, title, + win32con.WS_OVERLAPPEDWINDOW | win32con.WS_CLIPCHILDREN | win32con.WS_VISIBLE, + xpos, ypos, width, height, # xpos, ypos, width, height + 0, 0, wndclass.hInstance, None) + g_windows[windowID] = className + + if icon: + if bigIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_BIG, bigIcon) + if smallIcon: + win32api.SendMessage(windowID, win32con.WM_SETICON, win32con.ICON_SMALL, smallIcon) + + Debug("windowID = %s" % windowID) + return windowID + + +# Memory error when calling win32gui.DestroyWindow() +# after we called cefpython.CloseBrowser() + +def DestroyWindow(windowID): + + win32gui.DestroyWindow(windowID) + #className = GetWindowClassName(windowID) + #win32gui.UnregisterClass(className, None) + #del g_windows[windowID] # Let window with this className be created again. + + +def GetWindowClassName(windowID): + + for key in g_windows: + if key == windowID: + return g_windows[key] + +def MoveWindow(windowID, xpos=None, ypos=None, width=None, height=None, center=None): + + (left, top, right, bottom) = win32gui.GetWindowRect(windowID) + if xpos is None and ypos is None: + xpos = left + ypos = top + if width is None and height is None: + width = right - left + height = bottom - top + # Case: only ypos provided + if xpos is None and ypos is not None: + xpos = left + if ypos is None and xpos is not None: + ypos = top + # Case: only height provided + if not width: + width = right - left + if not height: + height = bottom - top + if center: + screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) + screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) + xpos = int(math.floor((screenx - width) / 2)) + ypos = int(math.floor((screeny - height) / 2)) + if xpos < 0: xpos = 0 + if ypos < 0: ypos = 0 + win32gui.MoveWindow(windowID, xpos, ypos, width, height, 1) + + +#noinspection PyUnusedLocal +def WM_CLOSE(windowID, msg, wparam, lparam): + + DestroyWindow(windowID) + win32gui.PostQuitMessage(0) + + +def GetLastError(): + + code = win32api.GetLastError() + return "(%d) %s" % (code, win32api.FormatMessage(code)) + +#noinspection PyUnusedLocal +def MessageLoop(className): + + while not win32gui.PumpWaitingMessages(): + time.sleep(0.001) + + +if __name__ == "__main__": + + g_debug = True + hwnd = CreateWindow("Test window", "testwindow", 800, 600) + MessageLoop("testwindow") \ No newline at end of file diff --git a/cefpython/cef3/windows/binaries_64bit/example.html b/cefpython/cef3/windows/binaries_64bit/example.html new file mode 100644 index 00000000..96bbac9b --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/example.html @@ -0,0 +1,58 @@ + + + + + CEF Python 3 example (utf-8: ąś) + + + + + + +

Use mouse context menu to go Back/Forward in history navigation.

+ + + +

Google Search

+https://www.google.com/ + + + +

User agent

+ + + + +

Popup

+ + window.open('example.html') + + + +

HTML5 video and accelerated content

+ +HTML 5 video
+ +Accelerated canvas
+ +Accelerated layers
+ + + +

Advanced example

+ +See the wxpython.py script for an advanced usage of CEF Python 3 +features - including javascript bindings, js and python callbacks, +client handlers and others. + + +



+



+



+



+ + + diff --git a/cefpython/cef3/windows/binaries_64bit/icon.ico b/cefpython/cef3/windows/binaries_64bit/icon.ico new file mode 100644 index 00000000..435045ae Binary files /dev/null and b/cefpython/cef3/windows/binaries_64bit/icon.ico differ diff --git a/cefpython/cef3/windows/binaries_64bit/prism.css b/cefpython/cef3/windows/binaries_64bit/prism.css new file mode 100644 index 00000000..f94cca7c --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/prism.css @@ -0,0 +1,130 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.builtin { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} + diff --git a/cefpython/cef3/windows/binaries_64bit/prism.js b/cefpython/cef3/windows/binaries_64bit/prism.js new file mode 100644 index 00000000..ebaa4b42 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/prism.js @@ -0,0 +1,5 @@ +/* http://prismjs.com/download.html?themes=prism&languages=clike+javascript+python */ +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(f instanceof r)){l.lastIndex=0;var h=l.exec(f);if(h){c&&(g=h[1].length);var d=h.index-1+g,h=h[0].slice(g),p=h.length,m=d+p,v=f.slice(0,d+1),y=f.slice(m+1),k=[u,1];v&&k.push(v);var b=new r(o,s?t.tokenize(h,s):h);k.push(b),y&&k.push(y),Array.prototype.splice.apply(a,k)}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.tokenize(a,t.languages[r]))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; diff --git a/cefpython/cef3/windows/binaries_64bit/pygtk_.py b/cefpython/cef3/windows/binaries_64bit/pygtk_.py new file mode 100644 index 00000000..8c143783 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/pygtk_.py @@ -0,0 +1,197 @@ +# An example of embedding CEF browser in PyGTK on Windows. +# Tested with PyGTK 2.24.10 + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (_exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pygtk_.py]: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class PyGTKExample: + mainWindow = None + container = None + browser = None + exiting = None + searchEntry = None + + def __init__(self): + gobject.timeout_add(10, self.OnTimer) + + self.mainWindow = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.mainWindow.connect('destroy', self.OnExit) + self.mainWindow.set_size_request(width=1024, height=768) + self.mainWindow.set_title('PyGTK CEF 3 example') + self.mainWindow.realize() + + self.container = gtk.DrawingArea() + self.container.set_property('can-focus', True) + self.container.connect('size-allocate', self.OnSize) + self.container.show() + + self.searchEntry = gtk.Entry() + # By default, clicking a GTK widget doesn't grab the focus away from a native Win32 control (browser). + self.searchEntry.connect('button-press-event', self.OnWidgetClick) + self.searchEntry.show() + + table = gtk.Table(3, 1, homogeneous=False) + self.mainWindow.add(table) + table.attach(self.CreateMenu(), 0, 1, 0, 1, yoptions=gtk.SHRINK) + table.attach(self.searchEntry, 0, 1, 1, 2, yoptions=gtk.SHRINK) + table.attach(self.container, 0, 1, 2, 3) + table.show() + + windowID = self.container.get_window().handle + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowID) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath('example.html')) + + self.mainWindow.show() + + # Browser took focus, we need to get it back and give to searchEntry. + self.mainWindow.get_window().focus() + self.searchEntry.grab_focus() + + def CreateMenu(self): + file = gtk.MenuItem('File') + file.show() + filemenu = gtk.Menu() + item = gtk.MenuItem('Open') + filemenu.append(item) + item.show() + item = gtk.MenuItem('Exit') + filemenu.append(item) + item.show() + file.set_submenu(filemenu) + about = gtk.MenuItem('About') + about.show() + menubar = gtk.MenuBar() + menubar.append(file) + menubar.append(about) + menubar.show() + return menubar + + def OnWidgetClick(self, widget, data): + self.mainWindow.get_window().focus() + + def OnTimer(self): + if self.exiting: + return False + cefpython.MessageLoopWork() + return True + + def OnFocusIn(self, widget, data): + # This function is currently not called by any of code, but if you would like + # for browser to have automatic focus add such line: + # self.mainWindow.connect('focus-in-event', self.OnFocusIn) + cefpython.WindowUtils.OnSetFocus(self.container.get_window().handle, 0, 0, 0) + + def OnSize(self, widget, sizeAlloc): + cefpython.WindowUtils.OnSize(self.container.get_window().handle, 0, 0, 0) + + def OnExit(self, widget, data=None): + self.exiting = True + gtk.main_quit() + +if __name__ == '__main__': + version = '.'.join(map(str, list(gtk.gtk_version))) + print('[pygtk_.py] GTK version: %s' % version) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable + "release_dcheck_enabled": True, # Enable only when debugging + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + } + + cefpython.Initialize(settings) + + gobject.threads_init() # Timer for the message loop + PyGTKExample() + gtk.main() + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_64bit/pyqt.py b/cefpython/cef3/windows/binaries_64bit/pyqt.py new file mode 100644 index 00000000..6c042261 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/pyqt.py @@ -0,0 +1,191 @@ +# An example of embedding CEF browser in a PyQt4 application. +# Tested with PyQt 4.10.3 (Qt 4.8.5). + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +from PyQt4 import QtGui +from PyQt4 import QtCore + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pyqt.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PyQT CEF 3 example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winId()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winId())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("example.html")) + self.show() + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("[pyqt.py] PyQt version: %s" % QtCore.PYQT_VERSION_STR) + print("[pyqt.py] QtCore version: %s" % QtCore.qVersion()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + settings = { + # "cache_path": "webcache/", # Disk cache + "debug": True, # cefpython debug messages in console and in log_file + "log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE + "log_file": GetApplicationPath("debug.log"), # Set to "" to disable. + "release_dcheck_enabled": True, # Enable only when debugging. + # This directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + } + + # Command line switches set programmatically + switches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "enable-media-stream": "", + # "--invalid-switch": "" -> Invalid switch name + } + + cefpython.Initialize(settings, switches) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_64bit/pyside.py b/cefpython/cef3/windows/binaries_64bit/pyside.py new file mode 100644 index 00000000..9e48cbf8 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/pyside.py @@ -0,0 +1,189 @@ +# An example of embedding CEF Python in PySide application. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import PySide +from PySide import QtGui +from PySide import QtCore +import ctypes + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("cefpython: WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainWindow(QtGui.QMainWindow): + mainFrame = None + + def __init__(self): + super(MainWindow, self).__init__(None) + self.createMenu() + self.mainFrame = MainFrame(self) + self.setCentralWidget(self.mainFrame) + self.resize(1024, 768) + self.setWindowTitle('PySide example') + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + def createMenu(self): + menubar = self.menuBar() + filemenu = menubar.addMenu("&File") + filemenu.addAction(QtGui.QAction("Open", self)) + filemenu.addAction(QtGui.QAction("Exit", self)) + aboutmenu = menubar.addMenu("&About") + + def focusInEvent(self, event): + cefpython.WindowUtils.OnSetFocus(int(self.centralWidget().winIdFixed()), 0, 0, 0) + + def closeEvent(self, event): + self.mainFrame.browser.CloseBrowser() + +class MainFrame(QtGui.QWidget): + browser = None + + def __init__(self, parent=None): + super(MainFrame, self).__init__(parent) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(int(self.winIdFixed())) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings={}, + navigateUrl=GetApplicationPath("example.html")) + self.show() + + def winIdFixed(self): + # PySide bug: QWidget.winId() returns , + # there is no easy way to convert it to int. + try: + return int(self.winId()) + except: + if sys.version_info[0] == 2: + ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p + ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCObject_AsVoidPtr(self.winId()) + elif sys.version_info[0] == 3: + ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p + ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object] + return ctypes.pythonapi.PyCapsule_GetPointer(self.winId(), None) + + def moveEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + + def resizeEvent(self, event): + cefpython.WindowUtils.OnSize(int(self.winIdFixed()), 0, 0, 0) + +class CefApplication(QtGui.QApplication): + timer = None + + def __init__(self, args): + super(CefApplication, self).__init__(args) + self.createTimer() + + def createTimer(self): + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.onTimer) + self.timer.start(10) + + def onTimer(self): + # The proper way of doing message loop should be: + # 1. In createTimer() call self.timer.start(0) + # 2. In onTimer() call MessageLoopWork() only when + # QtGui.QApplication.instance()->hasPendingEvents() returns False. + # But... there is a bug in Qt, hasPendingEvents() returns always true. + cefpython.MessageLoopWork() + + def stopTimer(self): + # Stop the timer after Qt message loop ended, calls to MessageLoopWork() + # should not happen anymore. + self.timer.stop() + +if __name__ == '__main__': + print("PySide version: %s" % PySide.__version__) + print("QtCore version: %s" % QtCore.__version__) + + sys.excepthook = ExceptHook + settings = {} + settings["log_file"] = GetApplicationPath("debug.log") + settings["log_severity"] = cefpython.LOGSEVERITY_INFO + settings["release_dcheck_enabled"] = True # Enable only when debugging + settings["browser_subprocess_path"] = "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + cefpython.Initialize(settings) + + app = CefApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + app.exec_() + app.stopTimer() + + # Need to destroy QApplication(), otherwise Shutdown() fails. + # Unset main window also just to be safe. + del mainWindow + del app + + cefpython.Shutdown() diff --git a/cefpython/cef3/windows/binaries_64bit/pywin32.py b/cefpython/cef3/windows/binaries_64bit/pywin32.py new file mode 100644 index 00000000..0d87e346 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/pywin32.py @@ -0,0 +1,152 @@ +# Example of embedding CEF browser using the PyWin32 extension. +# Tested with pywin32 version 218. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import cefwindow +import win32con +import win32gui +import win32api +import time + +DEBUG = True + +# ----------------------------------------------------------------------------- +# Helper functions. + +def Log(msg): + print("[pywin32.py] %s" % str(msg)) + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[pywin32.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +# ----------------------------------------------------------------------------- + +def CefAdvanced(): + sys.excepthook = ExceptHook + + appSettings = dict() + # appSettings["cache_path"] = "webcache/" # Disk cache + if DEBUG: + # cefpython debug messages in console and in log_file + appSettings["debug"] = True + cefwindow.g_debug = True + appSettings["log_file"] = GetApplicationPath("debug.log") + appSettings["log_severity"] = cefpython.LOGSEVERITY_INFO + appSettings["release_dcheck_enabled"] = True # Enable only when debugging + appSettings["browser_subprocess_path"] = "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess") + cefpython.Initialize(appSettings) + + wndproc = { + win32con.WM_CLOSE: CloseWindow, + win32con.WM_DESTROY: QuitApplication, + win32con.WM_SIZE: cefpython.WindowUtils.OnSize, + win32con.WM_SETFOCUS: cefpython.WindowUtils.OnSetFocus, + win32con.WM_ERASEBKGND: cefpython.WindowUtils.OnEraseBackground + } + + browserSettings = dict() + browserSettings["universal_access_from_file_urls_allowed"] = True + browserSettings["file_access_from_file_urls_allowed"] = True + + if os.path.exists("icon.ico"): + icon = os.path.abspath("icon.ico") + else: + icon = "" + + windowHandle = cefwindow.CreateWindow(title="pywin32 example", + className="cefpython3_example", width=1024, height=768, + icon=icon, windowProc=wndproc) + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(windowHandle) + browser = cefpython.CreateBrowserSync(windowInfo, browserSettings, + navigateUrl=GetApplicationPath("example.html")) + cefpython.MessageLoop() + cefpython.Shutdown() + +def CloseWindow(windowHandle, message, wparam, lparam): + browser = cefpython.GetBrowserByWindowHandle(windowHandle) + browser.CloseBrowser() + return win32gui.DefWindowProc(windowHandle, message, wparam, lparam) + +def QuitApplication(windowHandle, message, wparam, lparam): + win32gui.PostQuitMessage(0) + return 0 + +def GetPywin32Version(): + fixed_file_info = win32api.GetFileVersionInfo(win32api.__file__, '\\') + return fixed_file_info['FileVersionLS'] >> 16 + +if __name__ == "__main__": + Log("pywin32 version = %s" % GetPywin32Version()) + CefAdvanced() diff --git a/cefpython/cef3/windows/binaries_64bit/smoke.css b/cefpython/cef3/windows/binaries_64bit/smoke.css new file mode 100644 index 00000000..2936c818 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/smoke.css @@ -0,0 +1,110 @@ +.smoke-base { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + visibility: hidden; + opacity: 0; +} + +.smoke-base.smoke-visible { + opacity: 1; + visibility: visible; +} + +.smokebg { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.smoke-base .dialog { + position: absolute; +} + +.dialog-prompt { + margin-top: 15px; + text-align: center; +} + +.dialog-buttons { + margin: 20px 0 5px 0 +} + +.smoke { +} + +.dialog-buttons button { + display: inline-block; + vertical-align: baseline; + cursor: pointer; + font-family: Menlo, 'Andale Mono', monospace; + font-style: normal; + text-decoration: none; + border: 0; + outline: 0; + margin: 0 5px; + -webkit-background-clip: padding-box; + font-size: 13px; + line-height: 13px; + font-weight: normal; + padding: 9px 12px; +} + +.dialog-prompt input { + margin: 0; + border: 0; + font-family: sans-serif; + outline: none; + font-family: Menlo, 'Andale Mono', monospace; + border: 1px solid #aaa; + width: 75%; + display: inline-block; + background-color: transparent; + font-size: 16px; + padding: 8px; +} + +.smoke-base { + background: rgba(0,0,0,.3); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#90000000,endColorstr=#900000000); +} + +.smoke-base .dialog { + top: 25%; + width: 40%; + left: 50%; + margin-left: -20%; +} + +.smoke-base .dialog-inner { + padding: 15px; + + color:#202020; +} + +.smoke { + background-color: rgba(255,255,255,0.95); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff,endColorstr=#ffffff); + box-shadow: 0 2px 8px #666; +} + + +.dialog-buttons button { + background-color: rgba(0,0,0,.85); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#222222,endColorstr=#222222); + border-radius: 0; + color: #fff; +} + +button.cancel { + background-color: rgba(0,0,0,.40); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#444444,endColorstr=#444444); +} + +.queue{ + display:none; +} diff --git a/cefpython/cef3/windows/binaries_64bit/smoke.min.js b/cefpython/cef3/windows/binaries_64bit/smoke.min.js new file mode 100644 index 00000000..61fb4f0c --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/smoke.min.js @@ -0,0 +1 @@ +(function(e,t){var n={smoketimeout:[],init:false,zindex:1e3,i:0,bodyload:function(e){var r=t.createElement("div");r.setAttribute("id","smoke-out-"+e);r.className="smoke-base";r.style.zIndex=n.zindex;n.zindex++;t.body.appendChild(r)},newdialog:function(){var t=(new Date).getTime();t=Math.random(1,99)+t;if(!n.init){n.listen(e,"load",function(){n.bodyload(t)})}else{n.bodyload(t)}return t},forceload:function(){},build:function(t,r){n.i++;r.stack=n.i;t=t.replace(/\n/g,"
");t=t.replace(/\r/g,"
");var i="",s="OK",o="Cancel",u="",a="",f;if(r.type==="prompt"){i='
'+'"+"
"}if(r.params.ok){s=r.params.ok}if(r.params.cancel){o=r.params.cancel}if(r.params.classname){u=r.params.classname}if(r.type!=="signal"){a='
';if(r.type==="alert"){a+='"}else if(r.type==="quiz"){if(r.params.button_1){a+='"}if(r.params.button_2){a+='"}if(r.params.button_3){a+='"}if(r.params.button_cancel){a+='"}}else if(r.type==="prompt"||r.type==="confirm"){if(r.params.reverseButtons){a+='"+'"}else{a+='"+'"}}a+="
"}f='
'+'
'+'
'+t+i+a+"
"+"
";if(!n.init){n.listen(e,"load",function(){n.finishbuild(t,r,f)})}else{n.finishbuild(t,r,f)}},finishbuild:function(e,r,i){var s=t.getElementById("smoke-out-"+r.newid);s.className="smoke-base smoke-visible smoke-"+r.type;s.innerHTML=i;while(s.innerHTML===""){s.innerHTML=i}if(n.smoketimeout[r.newid]){clearTimeout(n.smoketimeout[r.newid])}n.listen(t.getElementById("smoke-bg-"+r.newid),"click",function(){n.destroy(r.type,r.newid);if(r.type==="prompt"||r.type==="confirm"||r.type==="quiz"){r.callback(false)}else if(r.type==="alert"&&typeof r.callback!=="undefined"){r.callback()}});switch(r.type){case"alert":n.finishbuildAlert(e,r,i);break;case"confirm":n.finishbuildConfirm(e,r,i);break;case"quiz":n.finishbuildQuiz(e,r,i);break;case"prompt":n.finishbuildPrompt(e,r,i);break;case"signal":n.finishbuildSignal(e,r,i);break;default:throw"Unknown type: "+r.type}},finishbuildAlert:function(r,i,s){n.listen(t.getElementById("alert-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13||t.keyCode===32||t.keyCode===27){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}}}},finishbuildConfirm:function(r,i,s){n.listen(t.getElementById("confirm-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});n.listen(t.getElementById("confirm-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(true)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13||t.keyCode===32){n.destroy(i.type,i.newid);i.callback(true)}else if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildQuiz:function(r,i,s){var o,u,a;n.listen(t.getElementById("quiz-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});if(o=t.getElementById("quiz-ok1-"+i.newid))n.listen(o,"click",function(){n.destroy(i.type,i.newid);i.callback(o.innerHTML)});if(u=t.getElementById("quiz-ok2-"+i.newid))n.listen(u,"click",function(){n.destroy(i.type,i.newid);i.callback(u.innerHTML)});if(a=t.getElementById("quiz-ok3-"+i.newid))n.listen(a,"click",function(){n.destroy(i.type,i.newid);i.callback(a.innerHTML)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildPrompt:function(r,i,s){var o=t.getElementById("dialog-input-"+i.newid);setTimeout(function(){o.focus();o.select()},100);n.listen(t.getElementById("prompt-cancel-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(false)});n.listen(t.getElementById("prompt-ok-"+i.newid),"click",function(){n.destroy(i.type,i.newid);i.callback(o.value)});t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===13){n.destroy(i.type,i.newid);i.callback(o.value)}else if(t.keyCode===27){n.destroy(i.type,i.newid);i.callback(false)}}},finishbuildSignal:function(r,i,s){t.onkeyup=function(t){if(!t){t=e.event}if(t.keyCode===27){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}}};n.smoketimeout[i.newid]=setTimeout(function(){n.destroy(i.type,i.newid);if(typeof i.callback!=="undefined"){i.callback()}},i.timeout)},destroy:function(e,r){var i=t.getElementById("smoke-out-"+r);if(e!=="quiz"){var s=t.getElementById(e+"-ok-"+r)}var o=t.getElementById(e+"-cancel-"+r);i.className="smoke-base";if(s){n.stoplistening(s,"click",function(){});t.onkeyup=null}if(e==="quiz"){var u=t.getElementsByClassName("quiz-button");for(var a=0;a + + + + wxPython CEF 3 example (utf-8: ąś) + + + + + + + + + +Use the mouse context menu to go Back/Forward in history navigation. + +

Table of contents

+
    +
  1. Google search
  2. +
  3. User agent
  4. +
  5. Popups
  6. +
  7. HTML 5 video
  8. +
  9. Developer Tools
  10. +
  11. Downloads
  12. +
  13. HTML controls
  14. +
  15. Browser object
  16. +
  17. Frame object
  18. +
  19. Javascript bindings
  20. +
  21. Javascript callbacks
  22. +
  23. Python callbacks
  24. +
  25. Display handler
  26. +
  27. Keyboard handler
  28. +
  29. Request handler
  30. +
  31. Cookie tests
  32. +
  33. Load handler
  34. +
  35. Javascript Dialog handler
  36. +
  37. Other tests
  38. +
+ + + + + + +

Google search

+ +http://www.google.com/ + + + + + + + +

User agent

+ + + + + + + + + +

Popups

+ +
    +
  1. + window.open('wxpython.html') +
  2. +
  3. + target=_blank href="wxpython.html" +
  4. +
  5. + window.open('https://www.google.com/') +
  6. +
+ +There are problems with keyboard in wxPython when popup windows are created +by CEF ( +Issue 80). To create the popup window of our own, the +LifespanHandler::OnBeforePopup callback was implemented. Note that this has +its implications, the popup window and parent window will not be able to +script each other. There will be no "window.opener" property available +in the popup window. + +See its source: + + + + +

CreateAnotherBrowser

+ +This will create a window on its own and embed browser in it. +When using "window.open" the window is created implicitilly +by CEF. You can intercept such popup creation using the +OnBeforePopup callback in LifespanHandler. You can return +True in OnBeforePopup and create popup window on your own +using the CreateAnotherBrowser function. + + + + external.CreateAnotherBrowser() + + + + + + + +

HTML5 video and accelerated content

+ + +HTML 5 video
+ + +Accelerated canvas
+ + +Accelerated layers
+ + + + + + +

Developer Tools

+ +You can open devtools popup window in a few different ways: +
    +
  1. Call Browser.ShowDevTools() method: + + external.ShowDevTools()
  2. +
  3. Through mouse context menu
  4. +
  5. Through F12 key which is handled in KeyboardHandler.OnKeyEvent
  6. +
+ + + + + + +

Downloads

+ +Download sample Ubuntu wallpapers:
+ + https://cefpython.googlecode.com/files/ubuntu-wallpapers2.zip + +

+Notes: On Linux it seems that OnLoadError with errorCode = ERR_ABORTED +is called even for successful downloads, you can ignore this behavior. +The proper console messages about successful/aborted download originate +from C++ Browser process code, these are: +

+ +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download completed, saved to: /Downloads/ubuntu-wallpapers2.zip
+
+ +If download was aborted the messages will be: + +
Browser: About to download file: ubuntu-wallpapers2.zip
+Browser: Download was cancelled
+
+ +

+Additionally on Linux there are more errors reported by Chromium +about org.gnome.SessionManager.inhibit. These can be safely ignored as well. +

+ +A download handler with callbacks like `OnBeforeDownload` and +`OnDownloadUpdated` may be exposed to CEF Python in the future. + + + + + + +

HTML controls

+ +

Textarea

+ +
+ +

Inputs

+Text:
+Password:
+ +

Select

+ + +

Buttons

+Submit:
+Button:
+ + + + + + +

Browser object

+ +Tests for the Browser object methods. + +

GoBack

+ +external.GoBack() + +

GoForward

+ +external.GoForward() + +

LoadUrl, GetUrl

+ + + window.open('data:text/html,Test#Browser.LoadUrl') + +

SetZoomLevel

+(You must set ApplicationSettings.auto_zooming = "" for SetZoomLevel calls +to work)
+external.SetZoomLevel(2.0)
+external.SetZoomLevel(1.0) + +

ReloadIgnoreCache, StopLoad

+Press F5 to reload page and ignore cache.
+Press Esc during webpage loading to abort.
+ +Also, when Esc is pressed OnLoadError may get called. See how abort +of page loading or file download is handled: + + + + + + + +

Frame object

+ +Tests for the Frame object methods. TODO. + + + + + + +

Javascript bindings

+ +

PyPrint

+ + + window.PyPrint('printing in python console from js') +
+ +

Window properties

+ +
jsBindings.SetProperty("pyProperty", "This was set in Python")
+jsBindings.SetProperty("pyConfig", ["This was set in Python",
+        {"name": "Nested dictionary", "isNested": True},
+        [1,"2", None]])
+
+ + + window.alert(window.pyProperty)
+ + window.alert(JSON.stringify(window.pyConfig)) +
+ +

Print

+ + + + external.Print('printing again from js') +
+ +

TestAllTypes

+ + + + external.TestAllTypes + (undefined, null, true, 1, + ((1<<31)>>>0), 2.14, 'Date not yet supported', 'string', + {key1: 1, key2: 2}, {key1: {'key1.1': 'nested object'}, 'key1.2': [1]}, + [1, 2], [1, [2.1, 'nested array']], [{key1: [{}]}]) +
+ +

ExecuteFunction

+ + + +
<script>
+function JavascriptAlert(message) { window.alert(message); }
+</script>
+
+ + + + external.ExecuteFunction('JavascriptAlert', + 'python called from js and then js called from python', 0, [1,2]) +
+ +

GetSource, GetText

+ + + + + + + external.GetSource() +
+ + external.GetText() + + + + + + +

Javascript callbacks

+ +

TestJSCallback

+ + + +
<script>
+function JSCallback(arg1) {
+    window.alert(arg1)
+}
+</script>
+
+ + + + external.TestJSCallback(JSCallback) + +

TestJSCallbackComplexArguments

+ + + +
<script>
+function JSCallback2() {
+    window.alert(JSON.stringify(arguments))
+}
+</script>
+
+ + + + external.TestJSCallbackComplexArguments({"myCallback": JSCallback2}) + + + + + + + +

Python callbacks

+ +

TestPythonCallback

+ + + +
<script>
+function JSCallback3(pyCallback) {
+    pyCallback(1, 2.14, "string", [1, [2, {"key": "value"}]], {"list": [1,2]});
+}
+</script>
+
+ + + + + + external.TestPythonCallback(JSCallback3) + + + + + + +

Display handler

+ +

OnAddressChange

+ +See messages in the console during loading of a webpage. + +

OnTitleChange

+ +See messages in the console during loading of a webpage. + +

OnTooltip

+ +See messages in the console when hovering over a google logo: +http://www.google.com/ + +

OnStatusMessage

+ +See messages in the console when hovering over links. + +

OnConsoleMessage

+ +Try this: + + http://patik.com/code/console-log-polyfill/ + + + + + + +

Keyboard handler

+ +

+ Press F5 to reload the page.
+ On Linux it is required to click anywhere in the window first + so that keyboard focus is set. See Issue 77 in the CEF Python + Issue Tracker. +

+ + + + + + + + + +

Request handler

+ +

OnBeforeResourceLoad

+ +See messages in the console. + +

OnResourceRedirect

+ +Try this: + + http://tinyurl.com/google404redirect + +

GetAuthCredentials

+ +Try this: + + http://browserspy.dk/password-ok.php + +

OnQuotaRequest

+ + + + +
<script>
+function DoRequestQuota() {
+    // Request Quota (only for File System API)
+    try {
+        navigator.webkitPersistentStorage.requestQuota(PERSISTENT, 1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    } catch(e) {
+        navigator.webkitPersistentStorage.requestQuota(1024*1024,
+                function(bytes){ window.alert("Granted bytes: "+bytes);},
+                function(error){ window.alert(error); });
+    }
+}
+</script>
+
+ +Try this: + + https://googledrive.com/host/0B1di2XiBBfacMnhRRkI1YlotUEk/requestquota.html + +

OnProtocolExecution

+ + +Try magnet link to download a torrent: + + magnet:?xt=urn:btih:a4224b45b27f436374391379cc5c7e629e2e5189 + +

_OnBeforePluginLoad

+ +Try OnBeforePluginLoad() with Flash: + + http://www.adobe.com/software/flash/about/ + +

_OnCertificateError

+ + +The url below won't be allowed. Click twice "Back" from context menu +to return back here after visiting that url:
+ + https://testssl-expire.disig.sk/index.en.html +
+ +This url will be allowed:
+ + https://testssl-expire.disig.sk/index.en.html?allow=1 +
+After you've clicked the second url, the first one will now be allowed, +as this is the same domain and it's cached now. + +

OnRendererProcessTerminated

+ +Try to terminate the "subprocess.exe" renderer process through +task manager. + +

OnPluginCrashed

+ +No test for that yet. + + + + + + +

Cookie tests

+ +See messages in the console. + +

GetCookieManager

+ + + +RequestHandler.GetCookieManager() - an example of having an unique +cookie manager for each browser. +
    +
  1. Visit the url below and set some cookies. Use "Back" from + context menu to get back here (you might have to click "Back" + multiple times).
    + Visit it in the current browser:
    + + http://www.html-kit.com/tools/cookietester/ +
  2. +
  3. Open cookietester in a popup - a separate cookie manager is used:
    + + javascript:external.CreateAnotherBrowser('http://www.html-kit.com/tools/cookietester/') +
  4. +
+ +

+Popup browsers created javascript's window.open share +the same renderer process and request context. If you want +to have separate cookie managers for popups created using +window.open then you have to implement the +LifespanHandler.`OnBeforePopup` callback. Return True in that +callback to cancel popup creation and instead create the +window on your own and embed browser in it. The CreateAnotherBrowser() +function from the wxpython example does that. +

+ +

VisitAllCookies

+ +Visit all cookies: +external.VisitAllCookies() +

+ +Note: visit some http:// webpage first, otherwise cookie manager is not +yet created. +
+ +

VisitUrlCookies

+ +Visit a subset of cookies for the given url: + + external.VisitUrlCookies("http://www.html-kit.com/tools/cookietester/") +
+ +

SetCookie

+ +Set a cookie on html-kit.com: +external.SetCookie() +
+Go see the cookie that was created: + + http://www.html-kit.com/tools/cookietester/ + +

DeleteCookies

+ +Delete the single cookie previously created via SetCookie(): + + external.DeleteCookies() +
+Go check if cookie was deleted: + + http://www.html-kit.com/tools/cookietester/ + + + + + + +

Load Handler

+ +See messages in the console during loading of a webpage. + +

OnLoadingStateChange

+ + +

OnLoadStart

+ + +

OnLoadEnd

+ + +

OnLoadError

+ +After you see the custom error message you have to hit +twice the Back from the context menu, to get back to this page. +
+Try this: + + http://www.non-existent.nono/ +
+ + + + + + + + +

Javascript Dialog Handler

+ +See messages in the console. + +

OnJavascriptDialog

+ + + window.alert('Test js dialog handler') + + +

OnBeforeUnloadJavascriptDialog

+ + + +
<script>
+function TestOnBeforeUnloadJavascriptDialog() {
+    window.onbeforeunload = function() {
+        return 'Testing the OnBeforeUnloadJavascriptDialog() callback';
+    }
+    location.href = "wxpython.html";
+}
+</script>
+
+ + + TestOnBeforeUnloadJavascriptDialog() + + +

OnResetJavascriptDialogState

+ + +

OnJavascriptDialogClosed

+ + + + + + + +

Other tests

+ +

HTTPS caching with SSL certificate errors

+Set ApplicationSettings["ignore_certificate_errors"] to True. + + + + + + + + + + + + + diff --git a/cefpython/cef3/windows/binaries_64bit/wxpython.py b/cefpython/cef3/windows/binaries_64bit/wxpython.py new file mode 100644 index 00000000..ed12af69 --- /dev/null +++ b/cefpython/cef3/windows/binaries_64bit/wxpython.py @@ -0,0 +1,910 @@ +# An example of embedding CEF browser in wxPython on Windows. +# Tested with wxPython 2.8.12.1 and 3.0.2.0. + +import os, sys +libcef_dll = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'libcef.dll') +if os.path.exists(libcef_dll): + # Import a local module + if (2,7) <= sys.version_info < (2,8): + import cefpython_py27 as cefpython + elif (3,4) <= sys.version_info < (3,4): + import cefpython_py34 as cefpython + else: + raise Exception("Unsupported python version: %s" % sys.version) +else: + # Import an installed package + from cefpython3 import cefpython + +import wx +import time +import re +import uuid +import platform +import inspect +import struct + +# ----------------------------------------------------------------------------- +# Globals + +g_applicationSettings = None +g_browserSettings = None +g_commandLineSwitches = None + +# Which method to use for message loop processing. +# EVT_IDLE - wx application has priority +# EVT_TIMER - cef browser has priority (default) +# It seems that Flash content behaves better when using a timer. +# Not sure if using EVT_IDLE is correct, it doesn't work on Linux, +# on Windows it works fine. See also the post by Robin Dunn: +# https://groups.google.com/d/msg/wxpython-users/hcNdMEx8u48/MD5Jgbm_k1kJ +USE_EVT_IDLE = False # If False then Timer will be used + +TEST_EMBEDDING_IN_PANEL = True + +# ----------------------------------------------------------------------------- + +def GetApplicationPath(file=None): + import re, os, platform + # On Windows after downloading file and calling Browser.GoForward(), + # current working directory is set to %UserProfile%. + # Calling os.path.dirname(os.path.realpath(__file__)) + # returns for eg. "C:\Users\user\Downloads". A solution + # is to cache path on first call. + if not hasattr(GetApplicationPath, "dir"): + if hasattr(sys, "frozen"): + dir = os.path.dirname(sys.executable) + elif "__file__" in globals(): + dir = os.path.dirname(os.path.realpath(__file__)) + else: + dir = os.getcwd() + GetApplicationPath.dir = dir + # If file is None return current directory without trailing slash. + if file is None: + file = "" + # Only when relative path. + if not file.startswith("/") and not file.startswith("\\") and ( + not re.search(r"^[\w-]+:", file)): + path = GetApplicationPath.dir + os.sep + file + if platform.system() == "Windows": + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return path + return str(file) + +def ExceptHook(excType, excValue, traceObject): + import traceback, os, time, codecs + # This hook does the following: in case of exception write it to + # the "error.log" file, display it to the console, shutdown CEF + # and exit application immediately by ignoring "finally" (os._exit()). + errorMsg = "\n".join(traceback.format_exception(excType, excValue, + traceObject)) + errorFile = GetApplicationPath("error.log") + try: + appEncoding = cefpython.g_applicationSettings["string_encoding"] + except: + appEncoding = "utf-8" + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace") + try: + with codecs.open(errorFile, mode="a", encoding=appEncoding) as fp: + fp.write("\n[%s] %s\n" % ( + time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg)) + except: + print("[wxpython.py] WARNING: failed writing to error file: %s" % ( + errorFile)) + # Convert error message to ascii before printing, otherwise + # you may get error like this: + # | UnicodeEncodeError: 'charmap' codec can't encode characters + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + cefpython.QuitMessageLoop() + cefpython.Shutdown() + os._exit(1) + +class MainFrame(wx.Frame): + browser = None + mainPanel = None + + def GetHandleForBrowser(self): + if self.mainPanel: + return self.mainPanel.GetHandle() + else: + return self.GetHandle() + + def __init__(self, url=None, popup=False): + if popup: + title = "wxPython Popup" + else: + title = "wxPython CEF 3 example" + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title=title) + size=(800,600) + + # This is an optional code to enable High DPI support. + if "auto_zooming" in g_applicationSettings \ + and g_applicationSettings["auto_zooming"] == "system_dpi": + # This utility function will adjust width/height using + # OS DPI settings. For 800/600 with Win7 DPI settings + # being set to "Larger 150%" will return 1200/900. + size = cefpython.DpiAware.CalculateWindowSize(size[0], size[1]) + + self.SetSize(size) + + if not url: + url = "file://"+GetApplicationPath("wxpython.html") + # Test hash in url. + # url += "#test-hash" + + self.CreateMenu() + + if TEST_EMBEDDING_IN_PANEL: + print("Embedding in a wx.Panel!") + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.mainPanel = wx.Panel(self, style=wx.WANTS_CHARS) + + # Global client callbacks must be set before browser is created. + self.clientHandler = ClientHandler() + cefpython.SetGlobalClientCallback("OnCertificateError", + self.clientHandler._OnCertificateError) + cefpython.SetGlobalClientCallback("OnBeforePluginLoad", + self.clientHandler._OnBeforePluginLoad) + cefpython.SetGlobalClientCallback("OnAfterCreated", + self.clientHandler._OnAfterCreated) + + windowInfo = cefpython.WindowInfo() + windowInfo.SetAsChild(self.GetHandleForBrowser()) + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings=g_browserSettings, + navigateUrl=url) + + self.clientHandler.mainBrowser = self.browser + self.browser.SetClientHandler(self.clientHandler) + + jsBindings = cefpython.JavascriptBindings( + bindToFrames=False, bindToPopups=True) + jsBindings.SetFunction("PyPrint", PyPrint) + jsBindings.SetProperty("pyProperty", "This was set in Python") + jsBindings.SetProperty("pyConfig", ["This was set in Python", + {"name": "Nested dictionary", "isNested": True}, + [1,"2", None]]) + self.javascriptExternal = JavascriptExternal(self.browser) + jsBindings.SetObject("external", self.javascriptExternal) + jsBindings.SetProperty("sources", GetSources()) + self.browser.SetJavascriptBindings(jsBindings) + + if self.mainPanel: + self.mainPanel.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.mainPanel.Bind(wx.EVT_SIZE, self.OnSize) + else: + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + if USE_EVT_IDLE and not popup: + # Bind EVT_IDLE only for the main application frame. + print("Using EVT_IDLE to execute the CEF message loop work") + self.Bind(wx.EVT_IDLE, self.OnIdle) + + def CreateMenu(self): + filemenu = wx.Menu() + filemenu.Append(1, "Open") + exit = filemenu.Append(2, "Exit") + self.Bind(wx.EVT_MENU, self.OnClose, exit) + aboutmenu = wx.Menu() + aboutmenu.Append(1, "CEF Python") + menubar = wx.MenuBar() + menubar.Append(filemenu,"&File") + menubar.Append(aboutmenu, "&About") + self.SetMenuBar(menubar) + + def OnSetFocus(self, event): + cefpython.WindowUtils.OnSetFocus(self.GetHandleForBrowser(), 0, 0, 0) + + def OnSize(self, event): + cefpython.WindowUtils.OnSize(self.GetHandleForBrowser(), 0, 0, 0) + + def OnClose(self, event): + # Remove all CEF browser references so that browser is closed + # cleanly. Otherwise there may be issues for example with cookies + # not being flushed to disk when closing app immediately + # (Issue 158). + del self.javascriptExternal.mainBrowser + del self.clientHandler.mainBrowser + del self.browser + + # Destroy wx frame, this will complete the destruction of CEF browser + self.Destroy() + + # In wx.chromectrl calling browser.CloseBrowser and/or self.Destroy + # may cause crashes when embedding multiple browsers in tab + # (Issue 107). In such case instead of calling CloseBrowser/Destroy + # try this code: + # | self.browser.ParentWindowWillClose() + # | event.Skip() + + def OnIdle(self, event): + cefpython.MessageLoopWork() + +def PyPrint(message): + print("[wxpython.py] PyPrint: "+message) + +class JavascriptExternal: + mainBrowser = None + stringVisitor = None + + def __init__(self, mainBrowser): + self.mainBrowser = mainBrowser + + def GoBack(self): + self.mainBrowser.GoBack() + + def GoForward(self): + self.mainBrowser.GoForward() + + def SetZoomLevel(self, zoomLevel): + self.mainBrowser.SetZoomLevel(zoomLevel) + + def CreateAnotherBrowser(self, url=None): + frame = MainFrame(url=url) + frame.Show() + + def Print(self, message): + print("[wxpython.py] Print: "+message) + + def TestAllTypes(self, *args): + print("[wxpython.py] TestAllTypes: "+str(args)) + + def ExecuteFunction(self, *args): + self.mainBrowser.ExecuteFunction(*args) + + def TestJSCallback(self, jsCallback): + print("[wxpython.py] jsCallback.GetFunctionName() = %s"\ + % jsCallback.GetFunctionName()) + print("[wxpython.py] jsCallback.GetFrame().GetIdentifier() = %s" % \ + jsCallback.GetFrame().GetIdentifier()) + jsCallback.Call("This message was sent from python using js callback") + + def TestJSCallbackComplexArguments(self, jsObject): + jsCallback = jsObject["myCallback"]; + jsCallback.Call(1, None, 2.14, "string", ["list", ["nested list", \ + {"nested object":None}]], \ + {"nested list next":[{"deeply nested object":1}]}) + + def TestPythonCallback(self, jsCallback): + jsCallback.Call(self.PyCallback) + + def PyCallback(self, *args): + message = "PyCallback() was executed successfully! "\ + "Arguments: %s" % str(args) + print("[wxpython.py] "+message) + self.mainBrowser.GetMainFrame().ExecuteJavascript( + "window.alert(\"%s\")" % message) + + def GetSource(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetSource(self.stringVisitor) + + def GetText(self): + # Must keep a strong reference to the StringVisitor object + # during the visit. + self.stringVisitor = StringVisitor() + self.mainBrowser.GetMainFrame().GetText(self.stringVisitor) + + def ShowDevTools(self): + print("[wxpython.py] external.ShowDevTools called") + self.mainBrowser.ShowDevTools() + + # ------------------------------------------------------------------------- + # Cookies + # ------------------------------------------------------------------------- + cookieVisitor = None + + def VisitAllCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitAllCookies(self.cookieVisitor) + + def VisitUrlCookies(self): + # Need to keep the reference alive. + self.cookieVisitor = CookieVisitor() + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.VisitUrlCookies( + "http://www.html-kit.com/tools/cookietester/", + False, self.cookieVisitor) + # .www.html-kit.com + + def SetCookie(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + "the cookietester website first and create some cookies") + return + cookie = cefpython.Cookie() + cookie.SetName("Created_Via_Python") + cookie.SetValue("yeah really") + cookieManager.SetCookie("http://www.html-kit.com/tools/cookietester/", + cookie) + print("\n[wxpython.py] Cookie created! Visit html-kit cookietester to"\ + " see it") + + def DeleteCookies(self): + cookieManager = self.mainBrowser.GetUserData("cookieManager") + if not cookieManager: + print("\n[wxpython.py] Cookie manager not yet created! Visit"\ + " the cookietester website first and create some cookies") + return + cookieManager.DeleteCookies( + "http://www.html-kit.com/tools/cookietester/", + "Created_Via_Python") + print("\n[wxpython.py] Cookie deleted! Visit html-kit cookietester "\ + "to see the result") + +class StringVisitor: + def Visit(self, string): + print("\n[wxpython.py] StringVisitor.Visit(): string:") + print("--------------------------------") + print(string) + print("--------------------------------") + +class CookieVisitor: + def Visit(self, cookie, count, total, deleteCookie): + if count == 0: + print("\n[wxpython.py] CookieVisitor.Visit(): total cookies: %s"\ + % total) + print("\n[wxpython.py] CookieVisitor.Visit(): cookie:") + print(" "+str(cookie.Get())) + # True to continue visiting cookies + return True + +class ClientHandler: + mainBrowser = None # May be None for global client callbacks. + + def __init__(self): + pass + + # ------------------------------------------------------------------------- + # DisplayHandler + # ------------------------------------------------------------------------- + + def OnAddressChange(self, browser, frame, url): + print("[wxpython.py] DisplayHandler::OnAddressChange()") + print(" url = %s" % url) + + def OnTitleChange(self, browser, title): + print("[wxpython.py] DisplayHandler::OnTitleChange()") + print(" title = %s" % title) + + def OnTooltip(self, browser, textOut): + # OnTooltip not yet implemented (both Linux and Windows), + # will be fixed in next CEF release, see Issue 783: + # https://code.google.com/p/chromiumembedded/issues/detail?id=783 + print("[wxpython.py] DisplayHandler::OnTooltip()") + print(" text = %s" % textOut[0]) + + statusMessageCount = 0 + def OnStatusMessage(self, browser, value): + if not value: + # Do not notify in the console about empty statuses. + return + self.statusMessageCount += 1 + if self.statusMessageCount > 3: + # Do not spam too much. + return + print("[wxpython.py] DisplayHandler::OnStatusMessage()") + print(" value = %s" % value) + + def OnConsoleMessage(self, browser, message, source, line): + print("[wxpython.py] DisplayHandler::OnConsoleMessage()") + print(" message = %s" % message) + print(" source = %s" % source) + print(" line = %s" % line) + + # ------------------------------------------------------------------------- + # KeyboardHandler + # ------------------------------------------------------------------------- + + def OnPreKeyEvent(self, browser, event, eventHandle, + isKeyboardShortcutOut): + print("[wxpython.py] KeyboardHandler::OnPreKeyEvent()") + + def OnKeyEvent(self, browser, event, eventHandle): + if event["type"] == cefpython.KEYEVENT_KEYUP: + # OnKeyEvent is called twice for F5/Esc keys, with event + # type KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP. + # Normal characters a-z should have KEYEVENT_CHAR. + return False + print("[wxpython.py] KeyboardHandler::OnKeyEvent()") + print(" type=%s" % event["type"]) + print(" modifiers=%s" % event["modifiers"]) + print(" windows_key_code=%s" % event["windows_key_code"]) + print(" native_key_code=%s" % event["native_key_code"]) + print(" is_system_key=%s" % event["is_system_key"]) + print(" character=%s" % event["character"]) + print(" unmodified_character=%s" % event["unmodified_character"]) + print(" focus_on_editable_field=%s" \ + % event["focus_on_editable_field"]) + linux = (platform.system() == "Linux") + windows = (platform.system() == "Windows") + # F5 + if (linux and event["native_key_code"] == 71) \ + or (windows and event["windows_key_code"] == 116): + print("[wxpython.py] F5 pressed, calling" + " browser.ReloadIgnoreCache()") + browser.ReloadIgnoreCache() + return True + # Escape + if (linux and event["native_key_code"] == 9) \ + or (windows and event["windows_key_code"] == 27): + print("[wxpython.py] Esc pressed, calling browser.StopLoad()") + browser.StopLoad() + return True + # F12 + if (linux and event["native_key_code"] == 96) \ + or (windows and event["windows_key_code"] == 123): + print("[wxpython.py] F12 pressed, calling" + " browser.ShowDevTools()") + browser.ShowDevTools() + return True + return False + + # ------------------------------------------------------------------------- + # RequestHandler + # ------------------------------------------------------------------------- + + def OnBeforeBrowse(self, browser, frame, request, isRedirect): + print("[wxpython.py] RequestHandler::OnBeforeBrowse()") + print(" url = %s" % request.GetUrl()[:100]) + # Handle "magnet:" links. + if request.GetUrl().startswith("magnet:"): + print("[wxpython.p] RequestHandler::OnBeforeBrowse(): " + "magnet link clicked, cancelling browse request") + return True + return False + + def OnBeforeResourceLoad(self, browser, frame, request): + print("[wxpython.py] RequestHandler::OnBeforeResourceLoad()") + print(" url = %s" % request.GetUrl()[:100]) + return False + + def OnResourceRedirect(self, browser, frame, oldUrl, newUrlOut): + print("[wxpython.py] RequestHandler::OnResourceRedirect()") + print(" old url = %s" % oldUrl[:100]) + print(" new url = %s" % newUrlOut[0][:100]) + + def GetAuthCredentials(self, browser, frame, isProxy, host, port, realm, + scheme, callback): + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::GetAuthCredentials()") + print(" host = %s" % host) + print(" realm = %s" % realm) + callback.Continue(username="test", password="test") + return True + + def OnQuotaRequest(self, browser, originUrl, newSize, callback): + print("[wxpython.py] RequestHandler::OnQuotaRequest()") + print(" origin url = %s" % originUrl) + print(" new size = %s" % newSize) + callback.Continue(True) + return True + + def GetCookieManager(self, browser, mainUrl): + # Create unique cookie manager for each browser. + # You must set the "unique_request_context_per_browser" + # application setting to True for the cookie manager + # to work. + # Return None to have one global cookie manager for + # all CEF browsers. + if not browser: + # The browser param may be empty in some exceptional + # case, see docs. + return None + cookieManager = browser.GetUserData("cookieManager") + if cookieManager: + return cookieManager + else: + print("[wxpython.py] RequestHandler::GetCookieManager():"\ + " created cookie manager") + cookieManager = cefpython.CookieManager.CreateManager("") + if "cache_path" in g_applicationSettings: + path = g_applicationSettings["cache_path"] + # path = os.path.join(path, "cookies_browser_{}".format( + # browser.GetIdentifier())) + cookieManager.SetStoragePath(path) + browser.SetUserData("cookieManager", cookieManager) + return cookieManager + + def OnProtocolExecution(self, browser, url, allowExecutionOut): + # There's no default implementation for OnProtocolExecution on Linux, + # you have to make OS system call on your own. You probably also need + # to use LoadHandler::OnLoadError() when implementing this on Linux. + print("[wxpython.py] RequestHandler::OnProtocolExecution()") + print(" url = %s" % url) + if url.startswith("magnet:"): + print("[wxpython.py] Magnet link allowed!") + allowExecutionOut[0] = True + + def _OnBeforePluginLoad(self, browser, url, policyUrl, info): + # This is a global callback set using SetGlobalClientCallback(). + # Plugins are loaded on demand, only when website requires it, + # the same plugin may be called multiple times. + # This callback is called on the IO thread, thus print messages + # may not be visible. + print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()") + print(" url = %s" % url) + print(" policy url = %s" % policyUrl) + print(" info.GetName() = %s" % info.GetName()) + print(" info.GetPath() = %s" % info.GetPath()) + print(" info.GetVersion() = %s" % info.GetVersion()) + print(" info.GetDescription() = %s" % info.GetDescription()) + # False to allow, True to block plugin. + return False + + def _OnCertificateError(self, certError, requestUrl, callback): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] RequestHandler::_OnCertificateError()") + print(" certError = %s" % certError) + print(" requestUrl = %s" % requestUrl) + if requestUrl == "https://testssl-expire.disig.sk/index.en.html": + print(" Not allowed!") + return False + if requestUrl \ + == "https://testssl-expire.disig.sk/index.en.html?allow=1": + print(" Allowed!") + callback.Continue(True) + return True + return False + + def OnRendererProcessTerminated(self, browser, status): + print("[wxpython.py] RequestHandler::OnRendererProcessTerminated()") + statuses = { + cefpython.TS_ABNORMAL_TERMINATION: "TS_ABNORMAL_TERMINATION", + cefpython.TS_PROCESS_WAS_KILLED: "TS_PROCESS_WAS_KILLED", + cefpython.TS_PROCESS_CRASHED: "TS_PROCESS_CRASHED" + } + statusName = "Unknown" + if status in statuses: + statusName = statuses[status] + print(" status = %s" % statusName) + + def OnPluginCrashed(self, browser, pluginPath): + print("[wxpython.py] RequestHandler::OnPluginCrashed()") + print(" plugin path = %s" % pluginPath) + + # ------------------------------------------------------------------------- + # LoadHandler + # ------------------------------------------------------------------------- + + def OnLoadingStateChange(self, browser, isLoading, canGoBack, + canGoForward): + print("[wxpython.py] LoadHandler::OnLoadingStateChange()") + print(" isLoading = %s, canGoBack = %s, canGoForward = %s" \ + % (isLoading, canGoBack, canGoForward)) + + def OnLoadStart(self, browser, frame): + print("[wxpython.py] LoadHandler::OnLoadStart()") + print(" frame url = %s" % frame.GetUrl()[:100]) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + print("[wxpython.py] LoadHandler::OnLoadEnd()") + print(" frame url = %s" % frame.GetUrl()[:100]) + # For file:// urls the status code = 0 + print(" http status code = %s" % httpStatusCode) + # Tests for the Browser object methods + self._Browser_LoadUrl(browser) + + def _Browser_LoadUrl(self, browser): + if browser.GetUrl() == "data:text/html,Test#Browser.LoadUrl": + browser.LoadUrl("file://"+GetApplicationPath("wxpython.html")) + + def OnLoadError(self, browser, frame, errorCode, errorTextList, failedUrl): + print("[wxpython.py] LoadHandler::OnLoadError()") + print(" frame url = %s" % frame.GetUrl()[:100]) + print(" error code = %s" % errorCode) + print(" error text = %s" % errorTextList[0]) + print(" failed url = %s" % failedUrl) + # Handle ERR_ABORTED error code, to handle the following cases: + # 1. Esc key was pressed which calls browser.StopLoad() in OnKeyEvent + # 2. Download of a file was aborted + # 3. Certificate error + if errorCode == cefpython.ERR_ABORTED: + print("[wxpython.py] LoadHandler::OnLoadError(): Ignoring load " + "error: Esc was pressed or file download was aborted, " + "or there was certificate error") + return; + customErrorMessage = "My custom error message!" + frame.LoadUrl("data:text/html,%s" % customErrorMessage) + + # ------------------------------------------------------------------------- + # LifespanHandler + # ------------------------------------------------------------------------- + + # ** This callback is executed on the IO thread ** + # Empty place-holders: popupFeatures, client. + def OnBeforePopup(self, browser, frame, targetUrl, targetFrameName, + popupFeatures, windowInfo, client, browserSettings, + noJavascriptAccess): + print("[wxpython.py] LifespanHandler::OnBeforePopup()") + print(" targetUrl = %s" % targetUrl) + + # Custom browser settings for popups: + # > browserSettings[0] = {"plugins_disabled": True} + + # Set WindowInfo object: + # > windowInfo[0] = cefpython.WindowInfo() + + # On Windows there are keyboard problems in popups, when popup + # is created using "window.open" or "target=blank". This issue + # occurs only in wxPython. PyGTK or PyQt do not require this fix. + # The solution is to create window explicitilly, and not depend + # on CEF to create window internally. See Issue 80 for details: + # https://code.google.com/p/cefpython/issues/detail?id=80 + + # If you set allowPopups=True then CEF will create popup window. + # The wx.Frame cannot be created here, as this callback is + # executed on the IO thread. Window should be created on the UI + # thread. One solution is to call cefpython.CreateBrowser() + # which runs asynchronously and can be called on any thread. + # The other solution is to post a task on the UI thread, so + # that cefpython.CreateBrowserSync() can be used. + + # Note that if you return True and create the popup window yourself, + # then the popup window and parent window will not be able to script + # each other. There will be no "window.opener" property available + # in the popup window. + + cefpython.PostTask(cefpython.TID_UI, self._CreatePopup, targetUrl) + + allowPopups = False + return not allowPopups + + def _CreatePopup(self, url): + frame = MainFrame(url=url, popup=True) + frame.Show() + + def _OnAfterCreated(self, browser): + # This is a global callback set using SetGlobalClientCallback(). + print("[wxpython.py] LifespanHandler::_OnAfterCreated()") + print(" browserId=%s" % browser.GetIdentifier()) + + def RunModal(self, browser): + print("[wxpython.py] LifespanHandler::RunModal()") + print(" browserId=%s" % browser.GetIdentifier()) + + def DoClose(self, browser): + print("[wxpython.py] LifespanHandler::DoClose()") + print(" browserId=%s" % browser.GetIdentifier()) + + def OnBeforeClose(self, browser): + print("[wxpython.py] LifespanHandler::OnBeforeClose") + print(" browserId=%s" % browser.GetIdentifier()) + + # ------------------------------------------------------------------------- + # JavascriptDialogHandler + # ------------------------------------------------------------------------- + + def OnJavascriptDialog(self, browser, originUrl, acceptLang, dialogType, + messageText, defaultPromptText, callback, + suppressMessage): + print("[wxpython.py] JavascriptDialogHandler::OnJavascriptDialog()") + print(" originUrl="+originUrl) + print(" acceptLang="+acceptLang) + print(" dialogType="+str(dialogType)) + print(" messageText="+messageText) + print(" defaultPromptText="+defaultPromptText) + # If you want to suppress the javascript dialog: + # suppressMessage[0] = True + return False + + def OnBeforeUnloadJavascriptDialog(self, browser, messageText, isReload, + callback): + print("[wxpython.py] OnBeforeUnloadJavascriptDialog()") + print(" messageText="+messageText) + print(" isReload="+str(isReload)) + # Return True if the application will use a custom dialog: + # callback.Continue(allow=True, userInput="") + # return True + return False + + def OnResetJavascriptDialogState(self, browser): + print("[wxpython.py] OnResetDialogState()") + + def OnJavascriptDialogClosed(self, browser): + print("[wxpython.py] OnDialogClosed()") + + +class MyApp(wx.App): + timer = None + timerID = 1 + mainFrame = None + + def OnInit(self): + if not USE_EVT_IDLE: + print("[wxpython.py] Using TIMER to run CEF message loop") + self.CreateTimer() + self.mainFrame = MainFrame() + self.SetTopWindow(self.mainFrame) + self.mainFrame.Show() + return True + + def CreateTimer(self): + # See "Making a render loop": + # http://wiki.wxwidgets.org/Making_a_render_loop + # Another approach is to use EVT_IDLE in MainFrame, + # see which one fits you better. + self.timer = wx.Timer(self, self.timerID) + self.timer.Start(10) # 10ms + wx.EVT_TIMER(self, self.timerID, self.OnTimer) + + def OnTimer(self, event): + cefpython.MessageLoopWork() + + def OnExit(self): + # When app.MainLoop() returns, MessageLoopWork() should + # not be called anymore. + print("[wxpython.py] MyApp.OnExit") + if not USE_EVT_IDLE: + self.timer.Stop() + + +def GetSources(): + # Get sources of all python functions and methods from this file. + # This is to provide sources preview to wxpython.html. + # The dictionary of functions is binded to "window.sources". + thisModule = sys.modules[__name__] + functions = inspect.getmembers(thisModule, inspect.isfunction) + classes = inspect.getmembers(thisModule, inspect.isclass) + sources = {} + for funcTuple in functions: + sources[funcTuple[0]] = inspect.getsource(funcTuple[1]) + for classTuple in classes: + className = classTuple[0] + classObject = classTuple[1] + methods = inspect.getmembers(classObject) + for methodTuple in methods: + try: + sources[methodTuple[0]] = inspect.getsource(\ + methodTuple[1]) + except: + pass + return sources + + +if __name__ == '__main__': + print('[wxpython.py] architecture=%s-bit' % (8 * struct.calcsize("P"))) + print('[wxpython.py] wx.version=%s' % wx.version()) + + # Intercept python exceptions. Exit app immediately when exception + # happens on any of the threads. + sys.excepthook = ExceptHook + + # Application settings + g_applicationSettings = { + # Disk cache + # "cache_path": "webcache/", + + # CEF Python debug messages in console and in log_file + "debug": True, + # Set it to LOGSEVERITY_VERBOSE for more details + "log_severity": cefpython.LOGSEVERITY_INFO, + # Set to "" to disable logging to a file + "log_file": GetApplicationPath("debug.log"), + # This should be enabled only when debugging + "release_dcheck_enabled": True, + + # These directories must be set on Linux + "locales_dir_path": cefpython.GetModuleDirectory()+"/locales", + "resources_dir_path": cefpython.GetModuleDirectory(), + # The "subprocess" executable that launches the Renderer + # and GPU processes among others. You may rename that + # executable if you like. + "browser_subprocess_path": "%s/%s" % ( + cefpython.GetModuleDirectory(), "subprocess"), + + # This option is required for the GetCookieManager callback + # to work. It affects renderer processes, when this option + # is set to True. It will force a separate renderer process + # for each browser created using CreateBrowserSync. + "unique_request_context_per_browser": True, + # Downloads are handled automatically. A default SaveAs file + # dialog provided by OS will be displayed. + + "downloads_enabled": True, + # Remote debugging port, required for Developer Tools support. + # A value of 0 will generate a random port. To disable devtools + # support set it to -1. + "remote_debugging_port": 0, + # Mouse context menu + "context_menu": { + "enabled": True, + "navigation": True, # Back, Forward, Reload + "print": True, + "view_source": True, + "external_browser": True, # Open in external browser + "devtools": True, # Developer Tools + }, + + # See also OnCertificateError which allows you to ignore + # certificate errors for specific websites. + "ignore_certificate_errors": True, + } + + # You can comment out the code below if you do not want High + # DPI support. If you disable it text will look fuzzy on + # high DPI displays. + # + # Enabling High DPI support in app can be done by + # embedding a DPI awareness xml manifest in executable + # (see Issue 112 comment #2), or by calling SetProcessDpiAware + # function. Embedding xml manifest is the most reliable method. + # The downside of calling SetProcessDpiAware is that scrollbar + # in CEF browser is smaller than it should be. This is because + # DPI awareness was set too late, after the CEF dll was loaded. + # To fix that embed DPI awareness xml manifest in the .exe file. + # + # There is one bug when enabling High DPI support - fonts in + # javascript dialogs (alert) are tiny. However, you can implement + # custom javascript dialogs using JavascriptDialogHandler. + # + # Additionally you have to set "auto_zomming" application + # setting. High DPI support is available only on Windows. + # You may set auto_zooming to "system_dpi" and browser + # contents will be zoomed using OS DPI settings. On Win7 + # these can be set in: Control Panel > Appearance and + # Personalization > Display. + # + # Example values for auto_zooming are: + # "system_dpi", "0.0" (96 DPI), "1.0" (120 DPI), + # "2.0" (144 DPI), "-1.0" (72 DPI) + # Numeric value means a zoom level. + # Example values that can be set in Win7 DPI settings: + # Smaller 100% (Default) = 96 DPI = 0.0 zoom level + # Medium 125% = 120 DPI = 1.0 zoom level + # Larger 150% = 144 DPI = 2.0 zoom level + # Custom 75% = 72 DPI = -1.0 zoom level + g_applicationSettings["auto_zooming"] = "system_dpi" + print("[wxpython.py] Calling SetProcessDpiAware") + cefpython.DpiAware.SetProcessDpiAware() + + # Browser settings. You may have different settings for each + # browser, see the call to CreateBrowserSync. + g_browserSettings = { + # "plugins_disabled": True, + # "file_access_from_file_urls_allowed": True, + # "universal_access_from_file_urls_allowed": True, + } + + # Command line switches set programmatically + g_commandLineSwitches = { + # "proxy-server": "socks5://127.0.0.1:8888", + # "no-proxy-server": "", + # "enable-media-stream": "", + # "disable-gpu": "", + + } + + cefpython.Initialize(g_applicationSettings, g_commandLineSwitches) + + app = MyApp(False) + app.MainLoop() + + # Let wx.App destructor do the cleanup before calling + # cefpython.Shutdown(). This is to ensure reliable CEF shutdown. + del app + + cefpython.Shutdown() + diff --git a/cefpython/cef3/windows/cefpython.rc b/cefpython/cef3/windows/cefpython.rc new file mode 100644 index 00000000..feb9c0a5 --- /dev/null +++ b/cefpython/cef3/windows/cefpython.rc @@ -0,0 +1,31 @@ +1 VERSIONINFO +FILEVERSION 31,2,0,0 +PRODUCTVERSION 31,2,0,0 +FILEFLAGSMASK 0x3FL +FILEFLAGS 0x0L +FILEOS 0x4L +FILETYPE 0x2L +FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "CEF Python" + VALUE "FileDescription", "CEF Python DLL" + VALUE "FileVersion", "31.2.0.0" + VALUE "InternalName", "cefpython" + VALUE "LegalCopyright", "(c) 2012 The CEF Python authors" + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "cefpython_py27.pyd" + VALUE "ProductName", "CEF Python 3" + VALUE "ProductVersion", "31.2.0.0" + VALUE "Comments", "Licensed under the BSD 3-clause license" + VALUE "Aditional Notes", "" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/cefpython/cef3/windows/compile.bat b/cefpython/cef3/windows/compile.bat new file mode 100644 index 00000000..eacaee71 --- /dev/null +++ b/cefpython/cef3/windows/compile.bat @@ -0,0 +1,235 @@ +@echo off + +:: It's best to always call with a flag that specifies python +:: version and architecture (eg. --py27-32bit). This will ensure +:: that PATH contains only minimum set of directories and will +:: allow to detect possible issues early. + +:: Arguments +if [%1] == [] ( + echo [compile.bat] Version number not provided. Usage: compile.bat 31.0 + echo [compile.bat] Opt: --rebuild --py27-32bit --py27-64bit --py34-32bit + echo --py34-64bit + exit /B 1 +) + +:: --rebuild flag to rebuild all vcproj builds +set rebuild_flag=0 +echo.%*|findstr /C:"--rebuild" >nul 2>&1 +if %errorlevel% equ 0 ( + set rebuild_flag=1 +) + +:: Add only Python/ to PATH. +:: --py27-32bit flag +echo.%*|findstr /C:"--py27-32bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27 +) +:: --py27-64bit flag +echo.%*|findstr /C:"--py27-64bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27_x64;C:\Python27_amd64;C:\Python27_64 +) +:: --py34-32bit flag +echo.%*|findstr /C:"--py34-32bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34 +) +:: --py34-64bit flag +echo.%*|findstr /C:"--py34-64bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34_x64;C:\Python34_amd64;C:\Python34_64 +) +:: PATH +echo [compile.bat] PATH: %PATH% + +:: Version number +set version=%1 +echo [compile.bat] Version argument: %version% + +:: Python architecture. %bits%=="32bit" or "64bit" +FOR /F "delims=" %%i IN ('python -c "import struct, sys; sys.stdout.write(str(8 * struct.calcsize('P')) + 'bit');"') do set bits=%%i +echo [compile.bat] Python architecture: %bits% + +:: Cython version +FOR /F "delims=" %%i IN ('python -c "import sys, Cython; sys.stdout.write(Cython.__version__);"') do set cython_version=%%i +echo [compile.bat] Cython version: %cython_version% + +:: Python version +for /F %%i in ('python -c "import sys; sys.stdout.write(str(sys.version_info[0])+str(sys.version_info[1]));"') do set pyver=%%i +echo [compile.bat] Python version: py%pyver% + +:: Binaries directory +set binaries=%~dp0binaries_%bits% +echo [compile.bat] Binaries directory: %binaries% + +:: Setup directory +set setup=%~dp0setup +echo [compile.bat] Setup directory: %setup% + +:: Delete .pyd files +echo [compile.bat] Cleaning cython build files from previous run +del "%binaries%\cefpython_py%pyver%.pyd" +del "%setup%\cefpython_py%pyver%.pyd" +for /R %setup% %%f in (*.pyx) do del "%%f" +rmdir /S /Q "%setup%\build\" + +:: Fix cefpython.h +echo [compile.bat] Fixing cefpython.h +cd %setup% +python fix_cefpython_h.py +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: failed to fix cefpython.h + cd ../ + exit /B 1 +) +cd ../ + +:: Compile VS projects: client_handler, libcefpythonapp, subprocess, cpp_utils + +:: client_handler paths +set client_handler_dir=%~dp0..\client_handler +set client_handler_vcproj=%client_handler_dir%\client_handler_py%pyver%_%bits%.vcproj + +set subprocess_dir=%~dp0..\subprocess + +:: libcefpythonapp paths +set libcefpythonapp_vcproj=%subprocess_dir%\libcefpythonapp_py%pyver%_%bits%.vcproj + +:: subprocess paths +set subprocess_vcproj=%subprocess_dir%\subprocess_%bits%.vcproj + +:: cpp_utils paths +set cpp_utils_dir=%~dp0..\..\cpp_utils +set cpp_utils_vcproj=%cpp_utils_dir%\cpp_utils_%bits%.vcproj + +set success=0 +if "%pyver%"=="27" ( + if "%bits%"=="32bit" ( + set "vcbuild=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe" + set success=1 + ) + if "%bits%"=="64bit" ( + REM :: The same vcbuild.exe 32-bit for building x64 + set "vcbuild=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe" + set success=1 + ) + set "vcoptions=/nocolor /nologo /nohtmllog" + if %rebuild_flag% equ 1 ( + set "vcoptions=%vcoptions% /rebuild" + ) +) +if "%pyver%"=="34" ( + :: In VS2010 vcbuild was replaced by msbuild.exe. + :: /clp:disableconsolecolor + :: msbuild /p:BuildProjectReferences=false project.proj + :: MSBuild.exe MyProject.proj /t:build +) + +if %success% neq 1 ( + echo [compile.bat] ERROR: failed determining tool to build vcproj files + exit /B 1 +) + +echo [compile.bat] Building client_handler vcproj +"%vcbuild%" %vcoptions% %client_handler_vcproj% +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: building client_handler vcproj failed + exit /B 1 +) + +echo [compile.bat] Building libcefpythonapp vcproj +"%vcbuild%" %vcoptions% %libcefpythonapp_vcproj% +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: building libcefpythonapp vcproj failed + exit /B 1 +) + +echo [compile.bat] Building subprocess vcproj +"%vcbuild%" %vcoptions% %subprocess_vcproj% +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: building subprocess vcproj failed + exit /B 1 +) + +echo [compile.bat] Building cpp_utils vcproj +"%vcbuild%" %vcoptions% %cpp_utils_vcproj% +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: building cpp_utils vcproj failed + exit /B 1 +) + +:: Do not clean VS build files, as this would slow down the process +:: of recompiling. + +:: Compile .rc file to a .res object. +echo [compile.bat] Compiling cefpython.rc file to a .res object +cd %setup%\ +python compile_rc.py -v %version% +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: compiling .rc file failed + exit /B 1 +) + +echo [compile.bat] Entering setup/ directory +cd %setup% + +echo [compile.bat] Copying .pyx files to setup/ directory and fixing includes +python fix_pyx_files.py +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: running fix_pyx_files.py failed + exit /B 1 +) + +:: __version__.pyx must be generated after running fix_pyx_files.py, +:: as that script deletes old pyx files before copying new ones. +echo [compile.bat] Creating __version__.pyx file +echo __version__ = "%version%">>__version__.pyx +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: writing __version__.pyx failed + exit /B 1 +) + +echo [compile.bat] Running the cython setup.py script +python setup.py build_ext --inplace +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: the cython setup.py script failed + :: Clean files from the build that failed + for /R %setup% %%f in (*.pyx) do del "%%f" + for /R %setup% %%f in (*.res) do del "%%f" + rmdir /S /Q "%setup%\build\" + cd ../ + exit /B 1 +) + +echo [compile.bat] Fixing cefpython.h +python fix_cefpython_h.py +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: failed to fix cefpython.h + exit /B 1 +) + +echo [compile.bat] Cleaning files from the build +for /R %setup% %%f in (*.pyx) do del "%%f" +for /R %setup% %%f in (*.res) do del "%%f" +rmdir /S /Q "%setup%\build\" + +echo [compile.bat] Moving the pyd module to the binaries directory +move "%setup%\cefpython_py%pyver%.pyd" "%binaries%/cefpython_py%pyver%.pyd" +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: Moving the pyd module failed + exit /B 1 +) + +echo [compile.bat] Copying subprocess.exe to the binaries directory +copy "%~dp0..\subprocess\Release_%bits%\subprocess_%bits%.exe" "%binaries%\subprocess.exe" +if %errorlevel% neq 0 ( + echo [compile.bat] ERROR: Copying subprocess.exe failed + exit /B 1 +) + +echo [compile.bat] Everything went OK. Running the wxpython.py example.. + +cd %binaries% +python wxpython.py & cd ../ diff --git a/cefpython/cef3/windows/compile.cmd b/cefpython/cef3/windows/compile.cmd new file mode 100644 index 00000000..1e7613c0 --- /dev/null +++ b/cefpython/cef3/windows/compile.cmd @@ -0,0 +1 @@ +cmd.exe /K compile.bat 99.99 diff --git a/cefpython/cef3/windows/installer/.gitignore b/cefpython/cef3/windows/installer/.gitignore new file mode 100644 index 00000000..0dc5ef2a --- /dev/null +++ b/cefpython/cef3/windows/installer/.gitignore @@ -0,0 +1,3 @@ +cefpython3-*/ +Output/ +dist/ diff --git a/cefpython/cef3/windows/installer/README.txt b/cefpython/cef3/windows/installer/README.txt new file mode 100644 index 00000000..2325940f --- /dev/null +++ b/cefpython/cef3/windows/installer/README.txt @@ -0,0 +1,18 @@ +1. To install CEF Python 3 type: + + python setup.py install + +2. In the same directory that setup.py resides there is + an examples/ directory, run some example scripts from there: + + cd examples/ + python wxpython.py + python pyqt.py + python pyside.py + python pygtk_.py + python pywin32.py + + cd wx/ + python sample1.py + python sample2.py + python sample3.py diff --git a/cefpython/cef3/windows/installer/__init__.py.template b/cefpython/cef3/windows/installer/__init__.py.template new file mode 100644 index 00000000..94ef341b --- /dev/null +++ b/cefpython/cef3/windows/installer/__init__.py.template @@ -0,0 +1,12 @@ +__all__ = ["cefpython", "wx"] +__version__ = "%(APP_VERSION)s" +__author__ = "The CEF Python authors" + +import sys + +if 0x02070000 <= sys.hexversion < 0x03000000: + from . import cefpython_py27 as cefpython +elif 0x03000000 <= sys.hexversion < 0x04000000: + from . import cefpython_py32 as cefpython +else: + raise Exception("Unsupported python version: " + sys.version) diff --git a/cefpython/cef3/windows/installer/build_all.bat b/cefpython/cef3/windows/installer/build_all.bat new file mode 100644 index 00000000..3c2dfdea --- /dev/null +++ b/cefpython/cef3/windows/installer/build_all.bat @@ -0,0 +1,213 @@ +@echo off +setlocal ENABLEDELAYEDEXPANSION + +:: It's best to always call with a flag that specifies python +:: version and architecture (eg. --py27-32bit). This will ensure +:: that PATH contains only minimum set of directories and will +:: allow to detect possible issues early. + +if "%1"=="" goto usage +if "%2"=="" goto usage + +set version=%1 + +:: Add only Python/ and Python/Scripts/ to PATH. +:: --py27-32bit flag +echo.%*|findstr /C:"--py27-32bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27;C:\Python27\Scripts +) +:: --py27-64bit flag +echo.%*|findstr /C:"--py27-64bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27_x64;C:\Python27_amd64;C:\Python27_64;C:\Python27_x64\Scripts;C:\Python27_amd64\Scripts;C:\Python27_64\Scripts +) +:: --py34-32bit flag +echo.%*|findstr /C:"--py34-32bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34;C:\Python34\Scripts +) +:: --py34-64bit flag +echo.%*|findstr /C:"--py34-64bit" >nul 2>&1 +if %errorlevel% equ 0 ( + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34_x64;C:\Python34_amd64;C:\Python34_64;C:\Python34_x64\Scripts;C:\Python34_amd64\Scripts;C:\Python34_64\Scripts +) +:: PATH +echo [compile.bat] PATH: %PATH% + +:: Python architecture. %bits%=="32bit" or "64bit" +FOR /F "delims=" %%i IN ('python -c "import struct, sys; sys.stdout.write(str(8 * struct.calcsize('P')) + 'bit');"') do set bits=%%i +echo [compile.bat] Python architecture: %bits% +set success=0 +if "%bits%"=="32bit" ( + set platform=win32 + set success=1 +) +if "%bits%"=="64bit" ( + set platform=win-amd64 + set success=1 +) +if %success% neq 1 ( + echo [build_all.bat] ERROR: invalid architecture: %bits% + exit /B 1 +) + +echo [build_all.bat] PLATFORM: %platform% +echo [build_all.bat] VERSION: %version% + +:: Python version +for /F %%i in ('python -c "import sys; sys.stdout.write(str(sys.version_info[0]) + '.' + str(sys.version_info[1]));"') do set pyverdot=%%i +echo [build_all.bat] Python version: py%pyverdot% + +:: --disable-inno-setup flag +set DISABLE_INNO_SETUP=0 +echo.%*|findstr /C:"--disable-inno-setup" >nul 2>&1 +if %errorlevel% equ 0 ( + set DISABLE_INNO_SETUP=1 +) + +:: Clean directories from previous run +rmdir /s /q Output +for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do rmdir /s /q %%f +rmdir /s /q dist + +mkdir dist + +echo [build_all.bat] Installing setuptools and wheel +pip install setuptools wheel +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: pip install setuptools wheel + exit /B 1 +) + +if %DISABLE_INNO_SETUP% equ 0 ( + echo [build_all.bat] Creating Inno Setup intaller + python make-installer.py -v %version% + if !errorlevel! equ 0 ( + for /f "tokens=*" %%f in ('dir .\Output\*.exe /b') do ( + move .\Output\%%f dist/%%f + if !errorlevel! neq 0 ( + echo [build_all.bat] ERROR: moving inno setup installer failed + exit /B 1 + ) + ) + rmdir Output + if !errorlevel! neq 0 ( + echo [build_all.bat] ERROR: deleting Output/ directory failed + exit /B 1 + ) + ) + if !errorlevel! neq 0 ( + echo [build_all.bat] ERROR: creating Inno Setup installer failed + exit /B 1 + ) +) + +echo [build_all.bat] Creating Distutils setup +python make-setup.py -v %version% +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating Distutils setup + exit /B 1 +) + +:: Enter the setup directory +for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do cd %%f + +echo [build_all.bat] Creating Distutils source package +python setup.py sdist +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating Distutils source package + exit /B 1 +) + +echo [build_all.bat] Creating Python Egg +python setup.py bdist_egg +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating Python Egg failed + exit /B 1 +) + +echo [build_all.bat] Creating Python Wheel +python setup.py bdist_wheel +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating Python Wheel failed + exit /B 1 +) + +echo [build_all.bat] Creating MSI installer +python setup.py bdist_msi +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating MSI installer failed + exit /B 1 +) + +echo [build_all.bat] Creating EXE installer +python setup.py bdist_wininst +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: creating EXE installer failed + exit /B 1 +) + +echo [build_all.bat] Moving all packages to the dist/ directory +set success=0 +for /f "tokens=*" %%f in ('dir .\dist\*.* /b') do ( + move .\dist\%%f .\..\dist\%%f + if !errorlevel! neq 0 ( + echo [build_all.bat] ERROR: moving setup dist/ packages failed + exit /B 1 + ) + if !errorlevel! equ 0 ( + set success=1 + ) +) +if %success% neq 1 ( + echo [build_all.bat] ERROR: moving setup dist/ packages failed + exit /B 1 +) + +:: Up to the installer/ directory +cd ../ + +echo [build_all.bat] Deleting the Distutils setup directory +for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do rmdir /s /q %%f +if %errorlevel% neq 0 ( + echo [build_all.bat] ERROR: failed deleting the Distutils setup directory + exit /B 1 +) + +cd dist/ + +echo [build_all.bat] Renaming some of the packages to include platform tag +for /R %%i in (*) do ( + set oldfile=%%i + set newfile=!oldfile:.egg=-%platform%.egg! + if "!oldfile!" neq "!newfile!" ( + move !oldfile! !newfile! + ) + set oldfile=%%i + set newfile=!oldfile:.zip=-py%pyverdot%-%platform%.zip! + if "!oldfile!" neq "!newfile!" ( + move !oldfile! !newfile! + ) + set oldfile=%%i + set newfile=!oldfile:%platform%.exe=py%pyverdot%-%platform%.exe! + if "!oldfile!" neq "!newfile!" ( + move !oldfile! !newfile! + ) + set oldfile=%%i + set newfile=!oldfile:%platform%.msi=py%pyverdot%-%platform%.msi! + if "!oldfile!" neq "!newfile!" ( + move !oldfile! !newfile! + ) +) + +echo [build_all.bat] Packages in the dist/ directory: +dir + +echo OK + +goto :eof +:usage +@echo [build_all.bat] ERROR: platform or version arguments missing or invalid +@echo [build_all.bat] ERROR: example usage: build_all.bat win32 31.2 +exit /B 1 diff --git a/cefpython/cef3/windows/installer/innosetup.template b/cefpython/cef3/windows/installer/innosetup.template new file mode 100644 index 00000000..e3a9a51e --- /dev/null +++ b/cefpython/cef3/windows/installer/innosetup.template @@ -0,0 +1,165 @@ +; Parts of this code was taken from wxPython/distrib/make_installer.py + +[Setup] + +AppName = CEF Python 3 for Python %(PYTHON_VERSION)s %(APP_NAME_BITS)s +AppVersion = %(APP_VERSION)s +AppVerName = CEF Python 3 version %(APP_VERSION)s for Python %(PYTHON_VERSION)s %(PYTHON_ARCHITECTURE)s + +AppPublisher = Czarek Tomczak +AppPublisherURL = http://code.google.com/cefpython/ +AppSupportURL = https://groups.google.com/group/cefpython?hl=en +AppUpdatesURL = http://code.google.com/cefpython/ +AppCopyright = Copyright 2012-2013 Czarek Tomczak + +DefaultDirName = {code:GetInstallDir|c:\Python} + +DefaultGroupName = CEF Python 3 for Python %(PYTHON_VERSION)s %(APP_NAME_BITS)s +PrivilegesRequired = none +DisableStartupPrompt = yes +Compression = zip +DirExistsWarning = no +DisableReadyMemo = yes +DisableReadyPage = yes +DisableDirPage = no +DisableProgramGroupPage = no +UsePreviousAppDir = yes +UsePreviousGroup = yes + +SourceDir = %(BINARIES_DIR)s +OutputDir = %(INSTALLER_DIR)s\Output +OutputBaseFilename = %(PACKAGE_NAME)s-%(APP_VERSION)s.%(PLATFORM)s-py%(PYTHON_VERSION)s-innosetup + +UninstallFilesDir = {app}\%(PACKAGE_NAME)s +LicenseFile = %(BINARIES_DIR)s\LICENSE.txt + +[Icons] + +Name: "{group}\Examples"; Filename: "{app}\%(PACKAGE_NAME)s\examples"; +Name: "{group}\Uninstall Package"; Filename: "{uninstallexe}"; + +[Run] + +Filename: "{app}\%(PACKAGE_NAME)s\examples"; Flags: postinstall skipifsilent shellexec; + +[Files] + +Source: "*.dll"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "locales\*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s\locales"; Flags: ignoreversion; +Source: "%(INSTALLER_DIR)s\__init__.py.generated"; DestDir: "{app}\%(PACKAGE_NAME)s"; DestName: "__init__.py"; Flags: ignoreversion; +Source: "cefclient.exe"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "cefpython_py%(PYTHON_VERSION_NODOT)s.pyd"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "LICENSE.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "README.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; +Source: "subprocess.exe"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; wx subpackage +; ------------------------------------------------------------------------------ + +Source: "%(WX_SUBPACKAGE_DIR)s\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\*.txt"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\images\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\wx\images"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; wx examples +; ------------------------------------------------------------------------------ + +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; +Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion; + +; ------------------------------------------------------------------------------ +; examples +; ------------------------------------------------------------------------------ + +Source: "*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "*.css"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "*.js"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; +Source: "*.ico"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion; + +[UninstallDelete] + +Type: files; Name: "{app}\%(PACKAGE_NAME)s\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\*.log"; +Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\__pycache__" + +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.log"; +Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\examples\__pycache__" + +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.log"; +Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\__pycache__" + +Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.pyc"; +Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.log"; +Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\wx\__pycache__" + +[Code] + +program Setup; +var + PythonDir : String; + InstallDir : String; + +function InitializeSetup(): Boolean; +begin + + if not RegQueryStringValue(%(HKEY_CURRENT_USER)s, + 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(%(HKEY_LOCAL_MACHINE)s, + 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(%(HKEY_CURRENT_USER)s, + 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + if not RegQueryStringValue(%(HKEY_LOCAL_MACHINE)s, + 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath', + '', PythonDir) then begin + + MsgBox('No installation of Python %(PYTHON_VERSION)s ' + + 'found in registry.' + #13 + 'Be sure to enter ' + + 'a pathname that places Python on the ' + + 'PYTHONPATH', + mbConfirmation, MB_OK); + PythonDir := 'C:\Python'; + end; + end; + end; + end; + + InstallDir := PythonDir + '\Lib\site-packages'; + Result := True; +end; + +function GetInstallDir(Default: String): String; +begin + Result := InstallDir; +end; + +function UninstallOld(FileName: String): Boolean; +var + ResultCode: Integer; +begin + Result := False; + if FileExists(FileName) then begin + Result := True; + Exec(FileName, '/SILENT', WizardDirValue(), SW_SHOWNORMAL, + ewWaitUntilTerminated, ResultCode); + end; +end; + +function NextButtonClick(CurPage: Integer): Boolean; +begin + Result := True; + if CurPage <> wpSelectDir then Exit; + UninstallOld(WizardDirValue() + '\%(PACKAGE_NAME)s\unins001.exe') + UninstallOld(WizardDirValue() + '\%(PACKAGE_NAME)s\unins000.exe') +end; diff --git a/cefpython/cef3/windows/installer/make-installer.py b/cefpython/cef3/windows/installer/make-installer.py new file mode 100644 index 00000000..ef8c715b --- /dev/null +++ b/cefpython/cef3/windows/installer/make-installer.py @@ -0,0 +1,94 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a Windows package installer. + +import sys +import os +import platform +import argparse +import re +import struct +import sysconfig + +BITS = str(8 * struct.calcsize('P')) + 'bit' +assert (BITS == "32bit" or BITS == "64bit") + +ISCC = r"c:\Program Files (x86)\Inno Setup 5\ISCC.exe" +if "INNO5" in os.environ: + ISCC = os.environ["INNO5"] + +TEMPLATE_FILE = os.getcwd()+r"\innosetup.template" +ISS_FILE = os.getcwd()+r"\innosetup.generated" + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), "Invalid version string" + + vars = {} + vars["PACKAGE_NAME"] = "cefpython3" + vars["APP_VERSION"] = args.version + vars["PYTHON_VERSION"] = (str(sys.version_info.major) + "." + + str(sys.version_info.minor)) + vars["PYTHON_VERSION_NODOT"] = (str(sys.version_info.major) + "" + + str(sys.version_info.minor)) + vars["PYTHON_ARCHITECTURE"] = platform.architecture()[0] + vars["BINARIES_DIR"] = os.path.realpath( + os.getcwd() + r"\..\binaries_%s" % BITS) + vars["PYD_FILE"] = (vars["BINARIES_DIR"]+r"\cefpython_py" + + str(sys.version_info.major) + str(sys.version_info.minor) + + ".pyd") + vars["INSTALLER_DIR"] = os.getcwd() + vars["WX_SUBPACKAGE_DIR"] = os.path.realpath(os.getcwd()+r"\..\.." + "\wx-subpackage") + vars["PLATFORM"] = sysconfig.get_platform() + + if BITS == "32bit": + # We must keep compatibility, 32bit installers didn't contain + # architecture information in AppName. So make it an empty string. + vars["APP_NAME_BITS"] = "" + vars["HKEY_CURRENT_USER"] = "HKEY_CURRENT_USER" + vars["HKEY_LOCAL_MACHINE"] = "HKEY_LOCAL_MACHINE" + elif BITS == "64bit": + vars["APP_NAME_BITS"] = "64bit" + # Inno setup installer is a 32bit application. To query 64bit + # registry from within 32bit application you need to add _64 + # postfix. + vars["HKEY_CURRENT_USER"] = "HKEY_CURRENT_USER_64" + vars["HKEY_LOCAL_MACHINE"] = "HKEY_LOCAL_MACHINE_64" + + print("Reading template: %s" % TEMPLATE_FILE) + + f = open(TEMPLATE_FILE) + template = f.read() + f.close() + + f = open(ISS_FILE, "w") + f.write(template % vars) + f.close() + + print("Saved: %s" % ISS_FILE) + + initPyTemplate = os.getcwd()+r"\__init__.py.template" + initPyInstall = os.getcwd()+r"\__init__.py.generated" + + f = open(initPyTemplate) + initPyTemplateCode = f.read() + f.close() + + f = open(initPyInstall, "w") + f.write(initPyTemplateCode % vars) + f.close() + print("Saved: %s" % initPyInstall) + + iscc_command = '"'+ ISCC + '" ' + ISS_FILE + print("Running ISCC: %s" % iscc_command) + exit_code = os.system(iscc_command) + sys.exit(exit_code) + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/windows/installer/make-setup.py b/cefpython/cef3/windows/installer/make-setup.py new file mode 100644 index 00000000..037237b4 --- /dev/null +++ b/cefpython/cef3/windows/installer/make-setup.py @@ -0,0 +1,178 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Create a setup package. + +import sys +import os +import platform +import argparse +import re +import platform +import shutil +import glob +import shutil +import sysconfig + +BITS = platform.architecture()[0] +assert (BITS == "32bit" or BITS == "64bit") + +PACKAGE_NAME = "cefpython3" + +README_FILE = os.getcwd()+r"/README.txt" +INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template" +SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template" +SETUP_CFG_TEMPLATE = os.getcwd()+r"/setup.cfg.template" + +def glob_remove(pathname): + filelist = glob.glob(pathname) + for f in filelist: + os.remove(f) + +def glob_copy(src_glob, dst_folder): + for fname in glob.iglob(src_glob): + print("Copying %s to %s" % (fname, dst_folder)) + if os.path.isdir(fname): + shutil.copytree(fname, + os.path.join(dst_folder, os.path.basename(fname))) + else: + shutil.copy(fname, + os.path.join(dst_folder, os.path.basename(fname))) + +def glob_move(src_glob, dst_folder): + if not os.path.exists(dst_folder): + os.mkdir(dst_folder) + for fname in glob.iglob(src_glob): + shutil.move(fname, + os.path.join(dst_folder, os.path.basename(fname))) + +def str_format(string, dictionary): + orig_string = string + for key, value in dictionary.iteritems(): + string = string.replace("%("+key+")s", value) + if string == orig_string: + raise Exception("Nothing to format") + if re.search(r"%\([a-zA-Z0-9_]+\)s", string): + raise Exception("Not all strings formatted") + return string + +def main(): + parser = argparse.ArgumentParser(usage="%(prog)s [options]") + parser.add_argument("-v", "--version", help="cefpython version", + required=True) + args = parser.parse_args() + assert re.search(r"^\d+\.\d+$", args.version), ( + "Invalid version string") + + vars = {} + vars["APP_VERSION"] = args.version + vars["PLATFORM"] = sysconfig.get_platform() + vars["PY_VERSION_DIGITS_ONLY"] = (str(sys.version_info.major) + "" + + str(sys.version_info.minor)) # "27" or "34" + + print("Reading template: %s" % README_FILE) + f = open(README_FILE) + README_CONTENT = f.read() + f.close() + + print("Reading template: %s" % INIT_TEMPLATE) + f = open(INIT_TEMPLATE) + INIT_CONTENT = str_format(f.read(), vars) + f.close() + + print("Reading template: %s" % SETUP_TEMPLATE) + f = open(SETUP_TEMPLATE) + SETUP_CONTENT = str_format(f.read(), vars) + f.close() + + print("Reading template: %s" % SETUP_CFG_TEMPLATE) + f = open(SETUP_CFG_TEMPLATE) + SETUP_CFG_CONTENT = str_format(f.read(), vars) + f.close() + + installer_dir = os.path.dirname(os.path.abspath(__file__)) + + pyVersion = str(sys.version_info.major) +"."+ str(sys.version_info.minor) + setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]\ + +"."+BITS+"-py"+pyVersion+"-setup" + print("Creating setup dir: "+setup_dir) + os.mkdir(setup_dir) + + package_dir = setup_dir+"/"+PACKAGE_NAME + #print("Creating package dir") + #os.mkdir(package_dir) + + print("Creating README.txt from template") + with open(setup_dir+"/README.txt", "w") as f: + f.write(README_CONTENT) + + print("Creating setup.py from template") + with open(setup_dir+"/setup.py", "w") as f: + f.write(SETUP_CONTENT) + + print("Creating setup.cfg from template") + with open(setup_dir+"/setup.cfg", "w") as f: + f.write(SETUP_CFG_CONTENT) + + binaries_dir = os.path.abspath(installer_dir+"/../binaries_"+BITS+"/") + print("Copying binaries to package dir") + shutil.copytree(binaries_dir, package_dir) + + os.chdir(package_dir) + print("Removing .log .pyc .pdb files from the package dir") + glob_remove("*.log") + glob_remove("*.pyc") + glob_remove("*.pdb") + + os.chdir(installer_dir) + + print("Creating __init__.py from template") + with open(package_dir+"/__init__.py", "w") as f: + f.write(INIT_CONTENT) + + print("Creating examples dir in package dir") + os.mkdir(package_dir+"/examples/") + + print("Creating wx dir in package dir") + os.mkdir(package_dir+"/wx/") + + print("Moving example scripts from package dir to examples dir") + examples = glob.glob(package_dir+"/*.py") + for example in examples: + # Ignore: cefpython_py27.py - dummy API script + if os.path.basename(example).startswith("cefpython_"): + continue + # Ignore: __init__.py + if os.path.basename(example).startswith("__"): + continue + os.rename(example, package_dir+"/examples/"+os.path.basename(example)) + glob_move(package_dir+"/*.html", package_dir+"/examples/") + glob_move(package_dir+"/*.css", package_dir+"/examples/") + glob_move(package_dir+"/*.js", package_dir+"/examples/") + + print("Copying wx-subpackage to wx dir in package dir") + wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx-subpackage/") + glob_copy(wx_subpackage_dir+"/*", package_dir+"/wx/") + + print("Moving wx examples from wx/examples to examples/wx") + glob_move(package_dir+"/wx/examples/*", package_dir+"/examples/wx/") + os.rmdir(package_dir+"/wx/examples/") + + print("Copying package dir examples to setup dir") + glob_copy(package_dir+"/examples/", setup_dir+"/examples/") + + # Create empty debug.log files so that package uninstalls cleanly + # in case examples were launched. Issue 149. + debug_log_dirs = [package_dir, + package_dir+"/examples/", + package_dir+"/examples/wx/"] + for dir in debug_log_dirs: + print("Creating empty debug.log in %s" % dir) + with open(dir+"/debug.log", "w") as f: + f.write("") + + print("Setup Package created successfully.") + +if __name__ == "__main__": + main() diff --git a/cefpython/cef3/windows/installer/setup.cfg.template b/cefpython/cef3/windows/installer/setup.cfg.template new file mode 100644 index 00000000..067dcbfd --- /dev/null +++ b/cefpython/cef3/windows/installer/setup.cfg.template @@ -0,0 +1,2 @@ +[bdist_wheel] +python-tag=cp%(PY_VERSION_DIGITS_ONLY)s diff --git a/cefpython/cef3/windows/installer/setup.py.template b/cefpython/cef3/windows/installer/setup.py.template new file mode 100644 index 00000000..36fb2809 --- /dev/null +++ b/cefpython/cef3/windows/installer/setup.py.template @@ -0,0 +1,68 @@ +try: + # The setuptools package is not installed by default + # on a clean Ubuntu. Might be also a case on Windows. + # Python Eggs and Wheels can be created only with setuptools. + from setuptools import setup + from setuptools.command.install import install as _install + from setuptools.dist import Distribution + print("[setup.py] Using setuptools") +except: + from distutils.core import setup + from distutils.command.install import install as _install + from distutils.dist import Distribution + print("[setup.py] Using distutils") + +import sys +import os +import subprocess + +def post_install(): + """ Post install tasks """ + print("[setup.py] post_install()") + # Nothing extra is required to do on Windows. + +class install(_install): + def run(self): + _install.run(self) + post_install() + +class BinaryDistribution(Distribution): + def is_pure(self): + return False + +setup( + distclass=BinaryDistribution, + cmdclass={'install': install}, + name='cefpython3', # No spaces here, so that it works with deb packages. + version='%(APP_VERSION)s', + description='Python bindings for the Chromium Embedded Framework', + license='BSD 3-Clause', + author='Czarek Tomczak', + author_email='czarek.tomczak@gmail.com', + url='http://code.google.com/p/cefpython/', + platforms=['%(PLATFORM)s'], + packages=['cefpython3', 'cefpython3.wx'], + package_data={'cefpython3': [ + 'examples/*.py', + 'examples/*.html', + 'examples/*.js', + 'examples/*.css', + 'examples/wx/*.py', + 'examples/wx/*.html', + 'examples/wx/*.js', + 'examples/wx/*.css', + 'examples/wx/*.png', + 'locales/*.pak', + 'wx/*.txt', + 'wx/images/*.png', + '*.txt', + 'cefclient.exe', + 'subprocess.exe', + '*.pyd', + '*.dll', + '*.pak', + 'debug.log', + 'examples/debug.log', + 'examples/wx/debug.log', + ]} +) diff --git a/cefpython/cef3/windows/setup/.gitignore b/cefpython/cef3/windows/setup/.gitignore new file mode 100644 index 00000000..d4b2c081 --- /dev/null +++ b/cefpython/cef3/windows/setup/.gitignore @@ -0,0 +1,3 @@ +*.cpp +*.pyx + diff --git a/cefpython/cef3/windows/setup/cefpython.h b/cefpython/cef3/windows/setup/cefpython.h new file mode 100644 index 00000000..67354266 --- /dev/null +++ b/cefpython/cef3/windows/setup/cefpython.h @@ -0,0 +1,95 @@ +#pragma warning(disable:4190) + +#ifndef __PYX_HAVE__cefpython_py27 +#define __PYX_HAVE__cefpython_py27 + + +#ifndef __PYX_HAVE_API__cefpython_py27 + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +__PYX_EXTERN_C DL_IMPORT(void) PyBrowser_ShowDevTools(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) PyTaskRunnable(int); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextCreated(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) V8ContextHandler_OnContextReleased(int, int64); +__PYX_EXTERN_C DL_IMPORT(void) V8FunctionHandler_Execute(CefRefPtr, CefRefPtr, CefString &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RemovePythonCallbacksForFrame(int); +__PYX_EXTERN_C DL_IMPORT(bool) ExecutePythonCallback(CefRefPtr, int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_OnBeforePopup(CefRefPtr, CefRefPtr, CefString const &, CefString const &, int const , CefWindowInfo &, CefRefPtr &, CefBrowserSettings &, bool *); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnAfterCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_RunModal(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_DoClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr, CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnTooltip(CefRefPtr, CefString &); +__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnStatusMessage(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) DisplayHandler_OnConsoleMessage(CefRefPtr, CefString const &, CefString const &, int); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnPreKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle, bool *); +__PYX_EXTERN_C DL_IMPORT(bool) KeyboardHandler_OnKeyEvent(CefRefPtr, CefKeyEvent const &, CefEventHandle); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeResourceLoad(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforeBrowse(CefRefPtr, CefRefPtr, CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetResourceHandler(CefRefPtr, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnResourceRedirect(CefRefPtr, CefRefPtr, CefString const &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr, CefRefPtr, bool, CefString const &, int, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnQuotaRequest(CefRefPtr, CefString const &, int64, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(CefRefPtr) RequestHandler_GetCookieManager(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnProtocolExecution(CefRefPtr, CefString const &, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforePluginLoad(CefRefPtr, CefString const &, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnCertificateError(int, CefString const &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnRendererProcessTerminated(CefRefPtr, enum cef_termination_status_t); +__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnPluginCrashed(CefRefPtr, CefString const &); +__PYX_EXTERN_C DL_IMPORT(bool) CookieVisitor_Visit(int, CefCookie const &, int, int, bool &); +__PYX_EXTERN_C DL_IMPORT(void) StringVisitor_Visit(int, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadingStateChange(CefRefPtr, bool, bool, bool); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadStart(CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadEnd(CefRefPtr, CefRefPtr, int); +__PYX_EXTERN_C DL_IMPORT(void) LoadHandler_OnLoadError(CefRefPtr, CefRefPtr, enum cef_errorcode_t, CefString const &, CefString const &); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnRenderProcessThreadCreated(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) BrowserProcessHandler_OnBeforeChildProcessLaunch(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetRootScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetViewRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenRect(CefRefPtr, CefRect &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenPoint(CefRefPtr, int, int, int &, int &); +__PYX_EXTERN_C DL_IMPORT(bool) RenderHandler_GetScreenInfo(CefRefPtr, CefScreenInfo &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupShow(CefRefPtr, bool); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPopupSize(CefRefPtr, CefRect const &); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnPaint(CefRefPtr, cef_paint_element_type_t, std::vector &, void const *, int, int); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnCursorChange(CefRefPtr, CefCursorHandle); +__PYX_EXTERN_C DL_IMPORT(void) RenderHandler_OnScrollOffsetChanged(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ProcessRequest(int, CefRefPtr, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_GetResponseHeaders(int, CefRefPtr, int64 &, CefString &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_ReadResponse(int, void *, int, int &, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanGetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(bool) ResourceHandler_CanSetCookie(int, CefCookie const &); +__PYX_EXTERN_C DL_IMPORT(void) ResourceHandler_Cancel(int); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnUploadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadProgress(int, CefRefPtr, uint64, uint64); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnDownloadData(int, CefRefPtr, void const *, size_t); +__PYX_EXTERN_C DL_IMPORT(void) WebRequestClient_OnRequestComplete(int, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) App_OnBeforeCommandLineProcessing_BrowserProcess(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnJavascriptDialog(CefRefPtr, CefString const &, CefString const &, enum cef_jsdialog_type_t, CefString const &, CefString const &, CefRefPtr, bool &); +__PYX_EXTERN_C DL_IMPORT(bool) JavascriptDialogHandler_OnBeforeUnloadJavascriptDialog(CefRefPtr, CefString const &, bool, CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnResetJavascriptDialogState(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) JavascriptDialogHandler_OnJavascriptDialogClosed(CefRefPtr); +__PYX_EXTERN_C DL_IMPORT(void) cefpython_GetDebugOptions(bool *, std::string *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBool(char const *); +__PYX_EXTERN_C DL_IMPORT(bool) ApplicationSettings_GetBoolFromDict(char const *, char const *); +__PYX_EXTERN_C DL_IMPORT(std::string) ApplicationSettings_GetString(char const *); +__PYX_EXTERN_C DL_IMPORT(int) CommandLineSwitches_GetInt(char const *); + +#endif /* !__PYX_HAVE_API__cefpython_py27 */ + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcefpython_py27(void); +#else +PyMODINIT_FUNC PyInit_cefpython_py27(void); +#endif + +#endif /* !__PYX_HAVE__cefpython_py27 */ diff --git a/cefpython/cef3/windows/setup/compile_rc.py b/cefpython/cef3/windows/setup/compile_rc.py new file mode 100644 index 00000000..8d53d8e2 --- /dev/null +++ b/cefpython/cef3/windows/setup/compile_rc.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Compile cefptython.rc to a .res object. +# In setup.py the .res object is added to Extension."extra_objects". + +import os +import sys +import re +import subprocess +import shutil + +PYVERSION = str(sys.version_info[0])+str(sys.version_info[1]) # eg. "27" +RC_EXE = r"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\rc.exe" +RC_FILE = os.path.abspath(r"../cefpython.rc") +RES_FILE_OUT = os.path.abspath(r"../cefpython.res") +RES_FILE_MOVE = os.path.abspath(r"./cefpython.res") +RC_PYD_NAME = r"cefpython_py27.pyd" + +def log(msg): + print("[compile_rc.py] %s" % str(msg)) + +def main(): + # Arguments + if len(sys.argv) == 3 \ + and sys.argv[1] == "-v" \ + and re.search(r"^\d+\.\d+$", sys.argv[2]): + version = sys.argv[2] + else: + log("Invalid version string or missing. Usage: compile_rc.py -v 31.0") + exit(1) + + # Print paths + log("version="+version) + log("PYVERSION="+PYVERSION) + log("RC_EXE="+RC_EXE) + log("RC_FILE="+RC_FILE) + log("RES_FILE_OUT="+RES_FILE_OUT) + log("RES_FILE_MOVE="+RES_FILE_MOVE) + log("RC_PYD_NAME="+RC_PYD_NAME) + + # Check paths + assert os.path.exists(RC_EXE) + assert os.path.exists(RC_FILE) + + # Change version numbers in .rc file + with open(RC_FILE, "r") as f: + contents = f.read() + # FILEVERSION 31,1,0,0 + # "FileVersion", "31.1.0.0" + (contents, subn) = re.subn( + r"\d+\.\d+\.\d+\.\d+", + r"%s.0.0" % version, + contents) + assert subn == 2, "Replacing dots versions failed (rc file)" + version_commas = re.sub(r"\.", r",", version) + (contents, subn) = re.subn( + r"\d+,\d+,\d+,\d+", + r"%s,0,0" % version_commas, + contents) + assert subn == 2, "Replacing commas verions failed (rc file)" + + # Change pyd module name in .rc + assert contents.find(RC_PYD_NAME) != -1, "pyd file name not found in .rc" + assert RC_PYD_NAME.find("py27") != -1, "invalid pyd file name defined" + new_pyd_name = RC_PYD_NAME.replace("py27", "py"+PYVERSION) + contents = contents.replace(RC_PYD_NAME, new_pyd_name) + + # Save modified .rc file + log("Saving modified %s" % RC_FILE) + with open(RC_FILE, "w") as f: + f.write(contents) + + log("Calling rc.exe to compile .rc file") + # rc.exe usage: rc.exe /x file.rc + # /x - ignore INCLUDE environment variable + exit_status = subprocess.call([ + RC_EXE, + "/x", + RC_FILE, + ], shell=True) + if exit_status != 0: + raise Exception("Calling rc.exe failed") + + log("Moving .res object to setup/") + shutil.move(RES_FILE_OUT, RES_FILE_MOVE) + + +if __name__ == '__main__': + main() diff --git a/cefpython/cef3/windows/setup/delete_pyx_files.bat b/cefpython/cef3/windows/setup/delete_pyx_files.bat new file mode 100644 index 00000000..ae1c5fbd --- /dev/null +++ b/cefpython/cef3/windows/setup/delete_pyx_files.bat @@ -0,0 +1,2 @@ +for /R %~dp0 %%f in (*.pyx) do del "%%f" +pause \ No newline at end of file diff --git a/cefpython/cef3/windows/setup/fix_cefpython_h.py b/cefpython/cef3/windows/setup/fix_cefpython_h.py new file mode 100644 index 00000000..dbcb535e --- /dev/null +++ b/cefpython/cef3/windows/setup/fix_cefpython_h.py @@ -0,0 +1,29 @@ +""" +Get rid of warnings like this: + + cefpython.h(36) : warning C4190: 'RequestHandler_GetResourceHandler' + has C-linkage specified, but returns UDT 'CefRefPtr' which is + incompatible with C +""" + +import os + + +def main(): + if not os.path.exists("cefpython.h"): + print("[fix_cefpython_h.py] cefpython.h was not yet generated") + return + with open("cefpython.h", "r") as fo: + content = fo.read() + pragma = "#pragma warning(disable:4190)" + if pragma in content: + print("[fix_cefpython_h.py] cefpython.h is already fixed") + return + content = ("%s\n\n" % (pragma)) + content + with open("cefpython.h", "w") as fo: + fo.write(content) + print("[fix_cefpython_h.py] Saved cefpthon.h") + + +if __name__ == '__main__': + main() diff --git a/cefpython/cef3/windows/setup/fix_pyx_files.py b/cefpython/cef3/windows/setup/fix_pyx_files.py new file mode 100644 index 00000000..33d3b55a --- /dev/null +++ b/cefpython/cef3/windows/setup/fix_pyx_files.py @@ -0,0 +1,107 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# First, it copies all .pyx files from upper directory to setup/. +# Then, fixes repeating of "include" statements in pyx files. + +# Only the mainfile needs to have "include" statements, +# but we're using PyCharm and to get rid of "unresolved references" +# and other errors displayed in pycharm we are adding "include" +# statements in all of the pyx files. + +# I'm not 100% sure how includes work in Cython, but I suspect that +# a few includes of the same file will include the same content more +# than once, it should work, but function and variable definitions are +# duplicated, it is some kind of overhead and it could lead to some +# problems in the future, better to fix it now. + +# It also checks cdef & cpdef functions whether they are not missing "except *", +# it is required to add it when returning non-python type. + +import glob +import os +import re +import shutil +import sys + +def ExceptAllMissing(content): + + # This is not perfect, won't detect C++ custom types, but will find + # the built-in types, templates and pointers. + patterns = [] + patterns.append( + r"\bcp?def\s+" + "((int|short|long|double|char|unsigned|float|double)\s+)+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A template ends with bracket: CefRefPtr[CefBrowser] + # or a pointer ends with asterisk: CefBrowser* + "[^\s]+[\]*]\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + patterns.append( + r"\bcp?def\s+" + # A reference, eg. CefString& + "[^\s]+&\s+" + "\w+\([^)]*\)\s*(with\s+(gil|nogil))?\s*:") + + for pattern in patterns: + match = re.search(pattern, content) + if match: break + + if match: + lineNumber = (content.count("\n", 0, match.start()) + 1) + return lineNumber + +print("\n") +mainfile = "cefpython.pyx" + +pyxfiles = glob.glob("../../../*.pyx") +if not len(pyxfiles): + sys.exit(1) +pyxfiles = [file for file in pyxfiles if file.find(mainfile) == -1] +# Now, pyxfiles contains all pyx files except the mainfile (cefpython.pyx), +# we do not fix includes in mainfile. + +# So that this is the right directory we're in. +if os.path.exists("setup"): + print("Wrong directory, we should be inside setup!") + sys.exit(1) + +# Remove old pyx files in setup directory. +oldpyxfiles = glob.glob("./*.pyx") +print("Removing old pyx files in /setup/: %s" % oldpyxfiles) +for pyxfile in oldpyxfiles: + if os.path.exists(pyxfile): + os.remove(pyxfile) + +# Copying pyxfiles and reading its contents. + +print("Copying .pyx files to /setup/: %s" % pyxfiles) +shutil.copy("../../../%s" % mainfile, "./%s" % mainfile) +# Rest of the files will be copied in for loop below. + +print("Fixing includes in .pyx files:") +for pyxfile in pyxfiles: + newfile = "./%s" % os.path.basename(pyxfile) + shutil.copy(pyxfile, newfile) + pyxfile = newfile + with open(pyxfile, "r") as pyxfileopened: + content = pyxfileopened.read() + lineNumber = ExceptAllMissing(content) + if lineNumber: + print("WARNING: 'except *' missing in a cdef/cpdef function, " + "in file %s on line %d" % (os.path.basename(pyxfile), lineNumber)) + sys.exit(1) + # Do not remove the newline - so that line numbers are exact with originals. + (content, subs) = re.subn(r"^include[\t ]+[\"'][^\"'\n\r]+[\"'][\t ]*", "", content, flags=re.MULTILINE) + if subs: + print("%s includes removed in: %s" % (subs, os.path.basename(pyxfile))) + # Reading and writing with the same handle using "r+" mode doesn't work, + # you need to seek(0) and write the same amount of bytes that was in the + # file, otherwise old data from the end of file stays. + with open(pyxfile, "w") as pyxfileopened: + pyxfileopened.write(content) + +print("\n") diff --git a/cefpython/cef3/windows/setup/lib_32bit/README b/cefpython/cef3/windows/setup/lib_32bit/README new file mode 100644 index 00000000..72d1c607 --- /dev/null +++ b/cefpython/cef3/windows/setup/lib_32bit/README @@ -0,0 +1 @@ +Put libcef.lib and libcef_dll_wrapper.lib here. diff --git a/cefpython/cef3/windows/setup/lib_64bit/README b/cefpython/cef3/windows/setup/lib_64bit/README new file mode 100644 index 00000000..72d1c607 --- /dev/null +++ b/cefpython/cef3/windows/setup/lib_64bit/README @@ -0,0 +1 @@ +Put libcef.lib and libcef_dll_wrapper.lib here. diff --git a/cefpython/cef3/windows/setup/setup.py b/cefpython/cef3/windows/setup/setup.py new file mode 100644 index 00000000..3a5cece3 --- /dev/null +++ b/cefpython/cef3/windows/setup/setup.py @@ -0,0 +1,118 @@ +from distutils.core import setup +from distutils.extension import Extension + +from Cython.Distutils import build_ext +from Cython.Compiler import Options +import Cython + +import sys +import platform +import struct +import os + +BITS = str(8 * struct.calcsize('P')) + "bit" + +print("[setup.py] Python architecture: %s" % BITS) +print("[setup.py] Cython version: %s" % Cython.__version__) + +# Stop on first error, otherwise hundreds of errors appear in the console. +Options.fast_fail = True + +# Written to cython_includes/compile_time_constants.pxi +CEF_VERSION = 3 + +# Python version string: "27" or "32". +PYVER = str(sys.version_info.major) + str(sys.version_info.minor) + +# Generate compile_time_constants.pxi +def CompileTimeConstants(): + print("[setup.py] Generating: cython_includes/compile_time_constants.pxi") + with open("../../../cython_includes/compile_time_constants.pxi", "w") as fd: + fd.write('# This file was generated by setup.py\n') + # A way around Python 3.2 bug: UNAME_SYSNAME is not set. + fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0]) + fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION) + fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major) +CompileTimeConstants() + +# Windows SDK Lib directory. +# It's also hardcoded in compile.bat +if BITS == "32bit": + winsdk_lib = r"C:\Program Files\Microsoft SDKs\Windows\v7.0\Lib" +elif BITS == "64bit": + winsdk_lib = r"C:\Program Files\Microsoft SDKs\Windows\v7.0\Lib\x64" +if not os.path.exists(winsdk_lib): + raise Exception("Windows SDK Lib directory not found: %s" % winsdk_lib) + +ext_modules = [Extension( + + "cefpython_py%s" % PYVER, + ["cefpython.pyx"], + + # Ignore the warning in the console: + # > C:\Python27\lib\distutils\extension.py:133: UserWarning: + # > Unknown Extension options: 'cython_directives' warnings.warn(msg) + cython_directives={ + # Any conversion to unicode must be explicit using .decode(). + "c_string_type": "bytes", + "c_string_encoding": "utf-8", + }, + + language='c++', + + include_dirs=[ + r'./../', + r'./../../', + r'./../../../', + r'./../../../cython_includes/'], + + library_dirs=[ + winsdk_lib, + r'./', + r'./lib_%s' % (BITS), + r'./../../client_handler/Release_py%s_%s/' % (PYVER, BITS), + r'./../../subprocess/Release_py%s_%s/' % (PYVER, BITS), + r'./../../../cpp_utils/Release_%s/' % (BITS), + ], + + libraries=[ + 'libcef', + 'libcef_dll_wrapper_md', + 'User32', + 'client_handler_py%s_%s' % (PYVER, BITS), + 'libcefpythonapp_py%s_%s' % (PYVER, BITS), + 'cpp_utils_%s' % (BITS), + ], + + extra_objects=[ + "cefpython.res" + ], + + # /EHsc - using STL string, multimap and others that use C++ exceptions. + # + # /ignore:4217 - disable warnings such as this: + # + # client_handler_py27_32bit.lib(client_handler.obj) : warning LNK4217: + # locally defined symbol _RemovePythonCallbacksForFrame imported in + # function "public: virtual bool __thiscall + # ClientHandler::OnProcessMessageReceived + # + # The above warning LNK4217 is caused by the warning below which occurs + # when building the client_handler.lib static library: + # + # cefpython.h(36) : warning C4190: 'RequestHandler_GetResourceHandler' + # has C-linkage specified, but returns UDT 'CefRefPtr' which is + # incompatible with C + # + # The C4190 warning is disabled with pragma in cefpython.h, see the + # fix_cefpython_h.py script. + + extra_compile_args=['/EHsc'], + extra_link_args=['/ignore:4217'] +)] + +setup( + name = 'cefpython_py%s' % PYVER, + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules +) diff --git a/cefpython/cef3/windows/stdint.h b/cefpython/cef3/windows/stdint.h new file mode 100644 index 00000000..d02608a5 --- /dev/null +++ b/cefpython/cef3/windows/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/cefpython/cef3/windows/wxpython.bat b/cefpython/cef3/windows/wxpython.bat new file mode 100644 index 00000000..a5b131aa --- /dev/null +++ b/cefpython/cef3/windows/wxpython.bat @@ -0,0 +1,3 @@ +cd binaries +call python "wxpython.py" +cd %~dp0 diff --git a/cefpython/cef3/wx-subpackage/README.txt b/cefpython/cef3/wx-subpackage/README.txt new file mode 100644 index 00000000..489dfc4c --- /dev/null +++ b/cefpython/cef3/wx-subpackage/README.txt @@ -0,0 +1,6 @@ +This is a wxPython subpackage for the cefpython3 package +that provides an easy to use API for the wxPython GUI library. + +Author: Greg Kacy +License: BSD 3-clause + diff --git a/cefpython/cef3/wx-subpackage/__init__.py b/cefpython/cef3/wx-subpackage/__init__.py new file mode 100644 index 00000000..340aae16 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/__init__.py @@ -0,0 +1,3 @@ +# This dummy file is overwritten by "__init__.py.template", see: +# cefpython/cef3/windows/installer/ +# cefpython/cef3/linux/installer/ diff --git a/cefpython/cef3/wx-subpackage/chromectrl.py b/cefpython/cef3/wx-subpackage/chromectrl.py new file mode 100644 index 00000000..4841e729 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/chromectrl.py @@ -0,0 +1,421 @@ +# Additional and wx specific layer of abstraction for the cefpython +# __author__ = "Greg Kacy " + +#------------------------------------------------------------------------------- + +from cefpython3 import cefpython +import os, sys, platform +import wx +import wx.lib.buttons as buttons + +#------------------------------------------------------------------------------- + +# CEF Python application settings +g_settings = None + +def Debug(msg): + if g_settings and "debug" in g_settings and g_settings["debug"]: + print("[chromectrl.py] "+msg) + +#------------------------------------------------------------------------------- + +# Default timer interval when timer used to service CEF message loop +DEFAULT_TIMER_MILLIS = 10 + +# A global timer for CEF message loop processing. +g_messageLoopTimer = None + +def CreateMessageLoopTimer(timerMillis): + # This function gets called multiple times for each ChromeWindow + # instance. + global g_messageLoopTimer + Debug("CreateMesageLoopTimer") + if g_messageLoopTimer: + return + g_messageLoopTimer = wx.Timer() + g_messageLoopTimer.Start(timerMillis) + Debug("g_messageLoopTimer.GetId() = "\ + +str(g_messageLoopTimer.GetId())) + wx.EVT_TIMER(g_messageLoopTimer, g_messageLoopTimer.GetId(),\ + MessageLoopTimer) + +def MessageLoopTimer(event): + cefpython.MessageLoopWork() + +def DestroyMessageLoopTimer(): + global g_messageLoopTimer + Debug("DestroyMessageLoopTimer") + if g_messageLoopTimer: + g_messageLoopTimer.Stop() + g_messageLoopTimer = None + else: + # There was no browser created during session. + Debug("DestroyMessageLoopTimer: timer not started") + +#------------------------------------------------------------------------------- + +class NavigationBar(wx.Panel): + def __init__(self, parent, *args, **kwargs): + wx.Panel.__init__(self, parent, *args, **kwargs) + + self.bitmapDir = os.path.join(os.path.dirname( + os.path.abspath(__file__)), "images") + + self._InitComponents() + self._LayoutComponents() + self._InitEventHandlers() + + def _InitComponents(self): + self.backBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Arrow Left.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + self.forwardBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Arrow Right.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + self.reloadBtn = buttons.GenBitmapButton(self, -1, + wx.Bitmap(os.path.join(self.bitmapDir, "Button Load.png"), + wx.BITMAP_TYPE_PNG), style=wx.BORDER_NONE) + + self.url = wx.TextCtrl(self, id=-1, style=0) + + self.historyPopup = wx.Menu() + + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.backBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.forwardBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.reloadBtn, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + + sizer.Add(self.url, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 12) + + self.SetSizer(sizer) + self.Fit() + + def _InitEventHandlers(self): + self.backBtn.Bind(wx.EVT_CONTEXT_MENU, self.OnButtonContext) + + def __del__(self): + self.historyPopup.Destroy() + + def GetBackButton(self): + return self.backBtn + + def GetForwardButton(self): + return self.forwardBtn + + def GetReloadButton(self): + return self.reloadBtn + + def GetUrlCtrl(self): + return self.url + + def InitHistoryPopup(self): + self.historyPopup = wx.Menu() + + def AddToHistory(self, url): + self.historyPopup.Append(-1, url) + + def OnButtonContext(self, event): + self.PopupMenu(self.historyPopup) + + +class ChromeWindow(wx.Window): + """ + Standalone CEF component. The class provides facilites for interacting + with wx message loop + """ + def __init__(self, parent, url="", useTimer=True, + timerMillis=DEFAULT_TIMER_MILLIS, browserSettings=None, + size=(-1, -1), *args, **kwargs): + wx.Window.__init__(self, parent, id=wx.ID_ANY, size=size, + *args, **kwargs) + + # This timer is not used anymore, but creating it for backwards + # compatibility. In one of external projects ChromeWindow.timer.Stop() + # is being called during browser destruction. + self.timer = wx.Timer() + + # On Linux absolute file urls need to start with "file://" + # otherwise a path of "/home/some" is converted to "http://home/some". + if platform.system() in ["Linux", "Darwin"]: + if url.startswith("/"): + url = "file://" + url + self.url = url + + windowInfo = cefpython.WindowInfo() + if platform.system() == "Windows": + windowInfo.SetAsChild(self.GetHandle()) + elif platform.system() == "Linux": + windowInfo.SetAsChild(self.GetGtkWidget()) + elif platform.system() == "Darwin": + (width, height) = self.GetClientSizeTuple() + windowInfo.SetAsChild(self.GetHandle(), + [0, 0, width, height]) + else: + raise Exception("Unsupported OS") + + if not browserSettings: + browserSettings = {} + + # Disable plugins: + # | browserSettings["plugins_disabled"] = True + + self.browser = cefpython.CreateBrowserSync(windowInfo, + browserSettings=browserSettings, navigateUrl=url) + + if platform.system() == "Windows": + self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + self.Bind(wx.EVT_SIZE, self.OnSize) + + self._useTimer = useTimer + if useTimer: + CreateMessageLoopTimer(timerMillis) + else: + # Currently multiple EVT_IDLE events might be registered + # when creating multiple ChromeWindow instances. This will + # result in calling CEF message loop work multiple times + # simultaneously causing performance penalties and possibly + # some unwanted behavior (CEF Python Issue 129). + Debug("WARNING: Using EVT_IDLE for CEF message loop processing"\ + " is not recommended") + self.Bind(wx.EVT_IDLE, self.OnIdle) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + if not self._useTimer: + try: + self.Unbind(wx.EVT_IDLE) + except: + # Calling Unbind() may cause problems on Windows 8: + # https://groups.google.com/d/topic/cefpython/iXE7e1ekArI/discussion + # (it was causing problems in __del__, this might not + # be true anymore in OnClose, but still let's make sure) + pass + self.browser.ParentWindowWillClose() + + def OnIdle(self, event): + """Service CEF message loop when useTimer is False""" + cefpython.MessageLoopWork() + event.Skip() + + def OnSetFocus(self, event): + """OS_WIN only.""" + cefpython.WindowUtils.OnSetFocus(self.GetHandle(), 0, 0, 0) + event.Skip() + + def OnSize(self, event): + """OS_WIN only. Handle the the size event""" + cefpython.WindowUtils.OnSize(self.GetHandle(), 0, 0, 0) + event.Skip() + + def GetBrowser(self): + """Returns the CEF's browser object""" + return self.browser + + def LoadUrl(self, url, onLoadStart=None, onLoadEnd=None): + if onLoadStart or onLoadEnd: + self.GetBrowser().SetClientHandler( + CallbackClientHandler(onLoadStart, onLoadEnd)) + + browser = self.GetBrowser() + if cefpython.g_debug: + Debug("LoadUrl() self: %s" % self) + Debug("browser: %s" % browser) + Debug("browser id: %s" % browser.GetIdentifier()) + Debug("mainframe: %s" % browser.GetMainFrame()) + Debug("mainframe id: %s" % \ + browser.GetMainFrame().GetIdentifier()) + self.GetBrowser().GetMainFrame().LoadUrl(url) + + #wx.CallLater(100, browser.ReloadIgnoreCache) + #wx.CallLater(200, browser.GetMainFrame().LoadUrl, url) + + +class ChromeCtrl(wx.Panel): + def __init__(self, parent, url="", useTimer=True, + timerMillis=DEFAULT_TIMER_MILLIS, + browserSettings=None, hasNavBar=True, + *args, **kwargs): + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + wx.Panel.__init__(self, parent, style=wx.WANTS_CHARS, *args, **kwargs) + + self.chromeWindow = ChromeWindow(self, url=str(url), useTimer=useTimer, + browserSettings=browserSettings) + sizer = wx.BoxSizer(wx.VERTICAL) + self.navigationBar = None + if hasNavBar: + self.navigationBar = self.CreateNavigationBar() + sizer.Add(self.navigationBar, 0, wx.EXPAND|wx.ALL, 0) + self._InitEventHandlers() + + sizer.Add(self.chromeWindow, 1, wx.EXPAND, 0) + + self.SetSizer(sizer) + self.Fit() + + ch = DefaultClientHandler(self) + self.SetClientHandler(ch) + if self.navigationBar: + self.UpdateButtonsState() + + def _InitEventHandlers(self): + self.navigationBar.backBtn.Bind(wx.EVT_BUTTON, self.OnLeft) + self.navigationBar.forwardBtn.Bind(wx.EVT_BUTTON, self.OnRight) + self.navigationBar.reloadBtn.Bind(wx.EVT_BUTTON, self.OnReload) + + def GetNavigationBar(self): + return self.navigationBar + + def SetNavigationBar(self, navigationBar): + sizer = self.GetSizer() + if self.navigationBar: + # remove previous one + sizer.Replace(self.navigationBar, navigationBar) + self.navigationBar.Hide() + del self.navigationBar + else: + sizer.Insert(0, navigationBar, 0, wx.EXPAND) + self.navigationBar = navigationBar + sizer.Fit(self) + + def CreateNavigationBar(self): + np = NavigationBar(self) + return np + + def SetClientHandler(self, handler): + self.chromeWindow.GetBrowser().SetClientHandler(handler) + + def OnLeft(self, event): + if self.chromeWindow.GetBrowser().CanGoBack(): + self.chromeWindow.GetBrowser().GoBack() + self.UpdateButtonsState() + self.chromeWindow.GetBrowser().SetFocus(True) + + def OnRight(self, event): + if self.chromeWindow.GetBrowser().CanGoForward(): + self.chromeWindow.GetBrowser().GoForward() + self.UpdateButtonsState() + self.chromeWindow.GetBrowser().SetFocus(True) + + def OnReload(self, event): + self.chromeWindow.GetBrowser().Reload() + self.UpdateButtonsState() + self.chromeWindow.GetBrowser().SetFocus(True) + + def UpdateButtonsState(self): + self.navigationBar.backBtn.Enable( + self.chromeWindow.GetBrowser().CanGoBack()) + self.navigationBar.forwardBtn.Enable( + self.chromeWindow.GetBrowser().CanGoForward()) + + def OnLoadStart(self, browser, frame): + if self.navigationBar: + self.UpdateButtonsState() + self.navigationBar.GetUrlCtrl().SetValue( + browser.GetMainFrame().GetUrl()) + self.navigationBar.AddToHistory(browser.GetMainFrame().GetUrl()) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + if self.navigationBar: + # In CEF 3 the CanGoBack() and CanGoForward() methods + # sometimes do work, sometimes do not, when called from + # the OnLoadStart event. That's why we're calling it again + # here. This is still not perfect as OnLoadEnd() is not + # guaranteed to get called for all types of pages. See the + # cefpython documentation: + # https://code.google.com/p/cefpython/wiki/LoadHandler + # OnDomReady() would be perfect, but is still not implemented. + # Another option is to implement our own browser state + # using the OnLoadStart and OnLoadEnd callbacks. + self.UpdateButtonsState() + +class DefaultClientHandler(object): + def __init__(self, parentCtrl): + self.parentCtrl = parentCtrl + + def OnLoadStart(self, browser, frame): + self.parentCtrl.OnLoadStart(browser, frame) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + self.parentCtrl.OnLoadEnd(browser, frame, httpStatusCode) + + def OnLoadError(self, browser, frame, errorCode, errorText, failedUrl): + # TODO + Debug("ERROR LOADING URL : %s" % failedUrl) + +class CallbackClientHandler(object): + def __init__(self, onLoadStart=None, onLoadEnd=None): + self._onLoadStart = onLoadStart + self._onLoadEnd = onLoadEnd + + def OnLoadStart(self, browser, frame): + if self._onLoadStart and frame.GetUrl() != "about:blank": + self._onLoadStart(browser, frame) + + def OnLoadEnd(self, browser, frame, httpStatusCode): + if self._onLoadEnd and frame.GetUrl() != "about:blank": + self._onLoadEnd(browser, frame, httpStatusCode) + + def OnLoadError(self, browser, frame, errorCode, errorText, failedUrl): + # TODO + Debug("ERROR LOADING URL : %s, %s" % (failedUrl, frame.GetUrl())) + +#------------------------------------------------------------------------------- + +def Initialize(settings=None, debug=False): + """Initializes CEF, We should do it before initializing wx + If no settings passed a default is used + """ + switches = {} + global g_settings + if not settings: + settings = {} + + if not "log_severity" in settings: + settings["log_severity"] = cefpython.LOGSEVERITY_INFO + if not "log_file" in settings: + settings["log_file"] = "" + + if platform.system() == "Linux": + # On Linux we need to set locales and resources directories. + if not "locales_dir_path" in settings: + settings["locales_dir_path"] = \ + cefpython.GetModuleDirectory() + "/locales" + if not "resources_dir_path" in settings: + settings["resources_dir_path"] = cefpython.GetModuleDirectory() + elif platform.system() == "Darwin": + # On Mac we need to set the resoures dir and the locale_pak switch + if not "resources_dir_path" in settings: + settings["resources_dir_path"] = (cefpython.GetModuleDirectory() + + "/Resources") + locale_pak = (cefpython.GetModuleDirectory() + + "/Resources/en.lproj/locale.pak") + if "locale_pak" in settings: + locale_pak = settings["locale_pak"] + del settings["locale_pak"] + switches["locale_pak"] = locale_pak + + if not "browser_subprocess_path" in settings: + settings["browser_subprocess_path"] = \ + "%s/%s" % (cefpython.GetModuleDirectory(), "subprocess") + + # DEBUGGING options: + # ------------------ + if debug: + settings["debug"] = True # cefpython messages in console and log_file + settings["log_severity"] = cefpython.LOGSEVERITY_VERBOSE + settings["log_file"] = "debug.log" # Set to "" to disable. + settings["release_dcheck_enabled"] = True + + g_settings = settings + cefpython.Initialize(settings, switches) + +def Shutdown(): + """Shuts down CEF, should be called by app exiting code""" + DestroyMessageLoopTimer() + cefpython.Shutdown() diff --git a/cefpython/cef3/wx-subpackage/examples/back.png b/cefpython/cef3/wx-subpackage/examples/back.png new file mode 100644 index 00000000..3e8f12fe Binary files /dev/null and b/cefpython/cef3/wx-subpackage/examples/back.png differ diff --git a/cefpython/cef3/wx-subpackage/examples/forward.png b/cefpython/cef3/wx-subpackage/examples/forward.png new file mode 100644 index 00000000..cfab7cfb Binary files /dev/null and b/cefpython/cef3/wx-subpackage/examples/forward.png differ diff --git a/cefpython/cef3/wx-subpackage/examples/reload_page.png b/cefpython/cef3/wx-subpackage/examples/reload_page.png new file mode 100644 index 00000000..3fa8db76 Binary files /dev/null and b/cefpython/cef3/wx-subpackage/examples/reload_page.png differ diff --git a/cefpython/cef3/wx-subpackage/examples/sample1.html b/cefpython/cef3/wx-subpackage/examples/sample1.html new file mode 100644 index 00000000..dd27ee41 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/examples/sample1.html @@ -0,0 +1,33 @@ + + + + + sample 1 + + + + +sample1.py - wxPython example for the CEF Python framework + +

Google Search

+ + http://www.google.com/ + +

User agent

+ + + +

Popup

+ + + window.open('sample1.html') + +










+










+










+ + + diff --git a/cefpython/cef3/wx-subpackage/examples/sample1.py b/cefpython/cef3/wx-subpackage/examples/sample1.py new file mode 100644 index 00000000..83d63f26 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/examples/sample1.py @@ -0,0 +1,60 @@ +# Simple sample ilustrating the usage of CEFWindow class. + +# On Mac the cefpython library must be imported the very first, +# before any other libraries (Issue 155). +import cefpython3.wx.chromectrl as chrome + +import os +import wx +import platform + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example1', size=(800,600)) + + self.cefWindow = chrome.ChromeWindow(self, + url=os.path.join(os.path.dirname(os.path.abspath(__file__)), + "sample1.html")) + + sizer = wx.BoxSizer() + sizer.Add(self.cefWindow, 1, wx.EXPAND, 0) + self.SetSizer(sizer) + + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + # Remember to destroy all CEF browser references before calling + # Destroy(), so that browser closes cleanly. In this specific + # example there are no references kept, but keep this in mind + # for the future. + self.Destroy() + # On Mac the code after app.MainLoop() never executes, so + # need to call CEF shutdown here. + if platform.system() == "Darwin": + chrome.Shutdown() + wx.GetApp().Exit() + +class MyApp(wx.App): + def OnInit(self): + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + +if __name__ == '__main__': + chrome.Initialize({ + "debug": True, + "log_file": "debug.log", + "log_severity": chrome.cefpython.LOGSEVERITY_INFO, + "release_dcheck_enabled": True, + # "cache_path": "webcache/", + }) + print('[sample1.py] wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown + del app + # On Mac Shutdown is called in OnClose + if platform.system() in ["Linux", "Windows"]: + chrome.Shutdown() diff --git a/cefpython/cef3/wx-subpackage/examples/sample2.py b/cefpython/cef3/wx-subpackage/examples/sample2.py new file mode 100644 index 00000000..3c218a5f --- /dev/null +++ b/cefpython/cef3/wx-subpackage/examples/sample2.py @@ -0,0 +1,121 @@ +# Slightly more advanced sample illustrating the usage of CEFWindow class. + +# On Mac the cefpython library must be imported the very first, +# before any other libraries (Issue 155). +import cefpython3.wx.chromectrl as chrome + +# TODO: There is something wrong happening on Linux. CPU usage +# for the python process is 100% all the time. This problem +# does not occur on Windows, nor in sample1.py/sample3.py. +# It must have something to do with invalid usage of the wx +# controls in this example. + +import wx +import wx.lib.agw.flatnotebook as fnb +import platform +import sys + +ROOT_NAME = "My Locations" + +URLS = ["http://gmail.com", + "http://maps.google.com", + "http://youtube.com", + "http://yahoo.com", + "http://wikipedia.com", + "http://cyaninc.com", + "http://tavmjong.free.fr/INKSCAPE/MANUAL/web/svg_tests.php" + ] + + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example2', size=(800, 600)) + + self.initComponents() + self.layoutComponents() + self.initEventHandlers() + if len(sys.argv) == 2 and sys.argv[1] == "test-launch": + wx.CallLater(500, self.testLaunch) + + def testLaunch(self): + # This hash is checked by /tests/test-launch.sh script + # to detect whether CEF initialized successfully. + print("b8ba7d9945c22425328df2e21fbb64cd") + self.Close() + + def initComponents(self): + self.tree = wx.TreeCtrl(self, id=-1, size=(200, -1)) + self.root = self.tree.AddRoot(ROOT_NAME) + for url in URLS: + self.tree.AppendItem(self.root, url) + self.tree.Expand(self.root) + + self.tabs = fnb.FlatNotebook(self, wx.ID_ANY, + agwStyle=fnb.FNB_NODRAG | fnb.FNB_X_ON_TAB) + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.tabs.SetWindowStyleFlag(wx.WANTS_CHARS) + + def layoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.tree, 0, wx.EXPAND) + sizer.Add(self.tabs, 1, wx.EXPAND) + self.SetSizer(sizer) + + def initEventHandlers(self): + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree) + self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosing) + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnSelChanged(self, event): + self.item = event.GetItem() + url = self.tree.GetItemText(self.item) + if url and url != ROOT_NAME: + cefPanel = chrome.ChromeCtrl(self.tabs, useTimer=True, url=str(url)) + self.tabs.AddPage(cefPanel, url) + self.tabs.SetSelection(self.tabs.GetPageCount()-1) + event.Skip() + + def OnPageClosing(self, event): + print("sample2.py: One could place some extra closing stuff here") + event.Skip() + + def OnClose(self, event): + # Remember to destroy all CEF browser references before calling + # Destroy(), so that browser closes cleanly. In this specific + # example there are no references kept, but keep this in mind + # for the future. + self.Destroy() + # On Mac the code after app.MainLoop() never executes, so + # need to call CEF shutdown here. + if platform.system() == "Darwin": + chrome.Shutdown() + wx.GetApp().Exit() + + +class MyApp(wx.App): + def OnInit(self): + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + +if __name__ == '__main__': + chrome.Initialize() + if platform.system() == "Linux": + # CEF initialization fails intermittently on Linux during + # launch of a subprocess (Issue 131). The solution is + # to offload cpu for half a second after Initialize + # has returned (it still runs some stuff in its thread). + import time + time.sleep(0.5) + print('sample2.py: wx.version=%s' % wx.version()) + app = MyApp(False) + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown + del app + # On Mac Shutdown is called in OnClose + if platform.system() in ["Linux", "Windows"]: + chrome.Shutdown() diff --git a/cefpython/cef3/wx-subpackage/examples/sample3.py b/cefpython/cef3/wx-subpackage/examples/sample3.py new file mode 100644 index 00000000..6df579a6 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/examples/sample3.py @@ -0,0 +1,104 @@ +# Slightly more advanced sample illustrating the usage of CEFWindow class. + +# On Mac the cefpython library must be imported the very first, +# before any other libraries (Issue 155). +import cefpython3.wx.chromectrl as chrome + +import os +import wx +import wx.lib.agw.flatnotebook as fnb +import platform + +class MainFrame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, + title='cefwx example3', size=(800,600)) + self._InitComponents() + self._LayoutComponents() + self._InitEventHandlers() + + def _InitComponents(self): + self.tabs = fnb.FlatNotebook(self, wx.ID_ANY, + agwStyle=fnb.FNB_NODRAG|fnb.FNB_X_ON_TAB) + # You also have to set the wx.WANTS_CHARS style for + # all parent panels/controls, if it's deeply embedded. + self.tabs.SetWindowStyleFlag(wx.WANTS_CHARS) + + ctrl1 = chrome.ChromeCtrl(self.tabs, useTimer=True, + url="wikipedia.org") + ctrl1.GetNavigationBar().GetUrlCtrl().SetEditable(False) + ctrl1.GetNavigationBar().GetBackButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "back.png"), wx.BITMAP_TYPE_PNG)) + ctrl1.GetNavigationBar().GetForwardButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "forward.png"), wx.BITMAP_TYPE_PNG)) + ctrl1.GetNavigationBar().GetReloadButton().SetBitmapLabel( + wx.Bitmap(os.path.join(os.path.dirname(os.path.abspath(__file__)), + "reload_page.png"), wx.BITMAP_TYPE_PNG)) + + self.tabs.AddPage(ctrl1, "Wikipedia") + + ctrl2 = chrome.ChromeCtrl(self.tabs, useTimer=True, url="google.com", + hasNavBar=False) + self.tabs.AddPage(ctrl2, "Google") + + ctrl3 = chrome.ChromeCtrl(self.tabs, useTimer=True, url="greenpeace.org") + ctrl3.SetNavigationBar(CustomNavigationBar(ctrl3)) + self.tabs.AddPage(ctrl3, "Greenpeace") + + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.tabs, 1, wx.EXPAND) + self.SetSizer(sizer) + + def _InitEventHandlers(self): + self.Bind(wx.EVT_CLOSE, self.OnClose) + + def OnClose(self, event): + # Remember to destroy all CEF browser references before calling + # Destroy(), so that browser closes cleanly. In this specific + # example there are no references kept, but keep this in mind + # for the future. + self.Destroy() + # On Mac the code after app.MainLoop() never executes, so + # need to call CEF shutdown here. + if platform.system() == "Darwin": + chrome.Shutdown() + wx.GetApp().Exit() + + +class CustomNavigationBar(chrome.NavigationBar): + def _LayoutComponents(self): + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.url, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 12) + + sizer.Add(self.GetBackButton(), 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + sizer.Add(self.GetForwardButton(), 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL| + wx.ALL, 0) + # in this example we dont want reload button + self.GetReloadButton().Hide() + self.SetSizer(sizer) + self.Fit() + + +class MyApp(wx.App): + def OnInit(self): + frame = MainFrame() + self.SetTopWindow(frame) + frame.Show() + return True + + +if __name__ == '__main__': + chrome.Initialize() + print('sample3.py: wx.version=%s' % wx.version()) + app = MyApp() + app.MainLoop() + # Important: do the wx cleanup before calling Shutdown + del app + # On Mac Shutdown is called in OnClose + if platform.system() in ["Linux", "Windows"]: + chrome.Shutdown() + diff --git a/cefpython/cef3/wx-subpackage/images/Arrow Left.png b/cefpython/cef3/wx-subpackage/images/Arrow Left.png new file mode 100644 index 00000000..640c707d Binary files /dev/null and b/cefpython/cef3/wx-subpackage/images/Arrow Left.png differ diff --git a/cefpython/cef3/wx-subpackage/images/Arrow Right.png b/cefpython/cef3/wx-subpackage/images/Arrow Right.png new file mode 100644 index 00000000..0321a83e Binary files /dev/null and b/cefpython/cef3/wx-subpackage/images/Arrow Right.png differ diff --git a/cefpython/cef3/wx-subpackage/images/Button Load.png b/cefpython/cef3/wx-subpackage/images/Button Load.png new file mode 100644 index 00000000..b7457a4a Binary files /dev/null and b/cefpython/cef3/wx-subpackage/images/Button Load.png differ diff --git a/cefpython/cef3/wx-subpackage/utils.py b/cefpython/cef3/wx-subpackage/utils.py new file mode 100644 index 00000000..c3a23f46 --- /dev/null +++ b/cefpython/cef3/wx-subpackage/utils.py @@ -0,0 +1,19 @@ +# Additional and wx specific layer of abstraction for the cefpython +# __author__ = "Greg Kacy " + +#------------------------------------------------------------------------------- + +def ExceptHook(excType, excValue, traceObject): + import traceback, os + errorMsg = "\n".join(traceback.format_exception( + excType, excValue, traceObject)) + if type(errorMsg) == bytes: + errorMsg = errorMsg.decode(encoding="ascii", errors="replace") + else: + errorMsg = errorMsg.encode("ascii", errors="replace") + errorMsg = errorMsg.decode("ascii", errors="replace") + print("\n"+errorMsg+"\n") + #cefpython.QuitMessageLoop() + #cefpython.Shutdown() + # So that "finally" does not execute. + #os._exit(1) diff --git a/cefpython/cefpython.pyx b/cefpython/cefpython.pyx new file mode 100644 index 00000000..691de13d --- /dev/null +++ b/cefpython/cefpython.pyx @@ -0,0 +1,503 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# IMPORTANT notes: +# +# - cdef/cpdef functions returning something other than a Python object +# should have in its declaration "except *", otherwise exceptions are +# ignored. Those cdef/cpdef that return "object" have "except *" by +# default. The setup/compile.py script will check for functions missing +# "except *" and will display an error message about that, but it's +# not perfect and won't detect all cases. +# +# - TODO: add checking for "except * with gil" in functions with the +# "public" keyword +# +# - about acquiring/releasing GIL lock, see discussion here: +# https://groups.google.com/forum/?fromgroups=#!topic/cython-users/jcvjpSOZPp0 +# +# - new ClientHandler() +# <...?> means to throw an error if the cast is not allowed +# +# - in client handler callbacks (or others that are called from C++ and +# use "except * with gil") must embrace all code in try..except otherwise +# the error will be ignored, only printed to the output console, this is the +# default behavior of Cython, to remedy this you are supposed to add "except *" +# in function declaration, unfortunately it does not work, some conflict with +# CEF threading, see topic at cython-users for more details: +# https://groups.google.com/d/msg/cython-users/CRxWoX57dnM/aufW3gXMhOUJ. +# +# - CTags requires all functions/methods imported in .pxd files to be preceded with "cdef", +# otherwise they are not indexed. +# +# - __del__ method does not exist in Extension Types (cdef class), +# you have to use __dealloc__ instead, try to remember that as +# defining __del__ will not raise any warning and could lead to +# memory leaks. +# +# - CefString.c_str() is safe to use only on Windows, on Ubuntu 64bit +# for a "Pers" string it returns: "P\x00e\x00r\x00s\x00", which is +# most probably not what you expected. +# +# - You can rename methods when importing in pxd files: +# | cdef cppclass _Object "Object": +# +# - Supporting operators that are not yet supported: +# | CefRefPtr[T]& Assign "operator="(T* p) +# | cefBrowser.Assign(CefBrowser*) +# In the same way you can import function with a different name, this one +# imports a static method Create() while adding a prefix "CefSome_": +# | cdef extern from "..": +# | static CefRefPtr[CefSome] CefSome_Create "CefSome::Create"() +# +# - Declaring C++ classes in Cython. Storing python callbacks +# in a C++ class using Py_INCREF, Py_DECREF. Calling from +# C++ using PyObject_CallMethod. +# | http://stackoverflow.com/a/17070382/623622 +# Disadvantage: when calling python callback from the C++ class +# declared in Cython there is no easy way to propagate the python +# exceptions when they occur during execution of the callback. +# +# - | cdef char* other_c_string = py_string +# This is a very fast operation after which other_c_string points +# to the byte string buffer of the Python string itself. It is +# tied to the life time of the Python string. When the Python +# string is garbage collected, the pointer becomes invalid. +# +# - When defining cpdef functions returning "cpp_bool": +# | cpdef cpp_bool myfunc() except *: +# Always do an additional cast when returning value, even when +# variable is defined as py_bool: +# | cdef py_bool returnValue +# | return bool(returnValue) +# Otherwise compiler warnings appear: +# | cefpython.cpp(26533) : warning C4800: 'int' : forcing value +# | to bool 'true' or 'false' (performance warning) +# Lots of these warnings results in ignoring them, but sometimes +# they are shown for a good reason. For example when you forget +# to return a value in a function. +# +# - Always import bool from libcpp as cpp_bool, if you import it as +# "bool" in a pxd file, then Cython will complain about bool casts +# like "bool(1)" being invalid, in pyx files. + +# All .pyx files need to be included in this file. +# Includes being made in other .pyx files are allowed to help +# IDE completion, but will be removed during cython compilation. + +# Version file is generated by the compile.bat/compile.py script. +include "__version__.pyx" + +include "cython_includes/compile_time_constants.pxi" +include "imports.pyx" + +# ----------------------------------------------------------------------------- +# Global variables + +g_debug = False +g_debugFile = "debug.log" + +# When put None here and assigned a local dictionary in Initialize(), later +# while running app this global variable was garbage collected, see topic: +# https://groups.google.com/d/topic/cython-users/0dw3UASh7HY/discussion +g_applicationSettings = {} +g_commandLineSwitches = {} + +cdef dict g_globalClientCallbacks = {} + +# If ApplicationSettings.unique_request_context_per_browser is False +# then a shared request context is used for all browsers. Otherwise +# a unique one is created for each call to CreateBrowserSync. +cdef CefRefPtr[CefRequestContext] g_sharedRequestContext + +# ----------------------------------------------------------------------------- + +include "utils.pyx" +include "string_utils.pyx" +IF UNAME_SYSNAME == "Windows": + include "string_utils_win.pyx" +include "time_utils.pyx" + +include "browser.pyx" +include "frame.pyx" + +include "settings.pyx" +IF UNAME_SYSNAME == "Windows" and CEF_VERSION == 1: + # Off-screen rendering currently supported only on Windows + include "paint_buffer_cef1.pyx" + +IF UNAME_SYSNAME == "Windows": + include "window_utils_win.pyx" + include "dpi_aware_win.pyx" + IF CEF_VERSION == 1: + include "http_authentication_win.pyx" +ELIF UNAME_SYSNAME == "Linux": + include "window_utils_linux.pyx" +ELIF UNAME_SYSNAME == "Darwin": + include "window_utils_mac.pyx" + +include "task.pyx" + +include "javascript_bindings.pyx" +include "virtual_keys.pyx" + +IF CEF_VERSION == 1: + include "window_info_cef1.pyx" + include "cookie_cef1.pyx" + include "load_handler_cef1.pyx" + include "keyboard_handler_cef1.pyx" + include "request_cef1.pyx" + include "web_request_cef1.pyx" + include "stream.pyx" + include "content_filter.pyx" + include "request_handler_cef1.pyx" + include "response_cef1.pyx" + include "display_handler_cef1.pyx" + include "lifespan_handler_cef1.pyx" + IF UNAME_SYSNAME == "Windows": + # Off-screen rendering currently supported only on Windows. + include "render_handler_cef1.pyx" + include "drag_data.pyx" + include "drag_handler.pyx" + include "download_handler.pyx" + include "v8context_handler_cef1.pyx" + include "v8function_handler_cef1.pyx" + include "v8utils_cef1.pyx" + include "javascript_callback_cef1.pyx" + include "python_callback_cef1.pyx" + include "network_error_cef1.pyx" + +IF CEF_VERSION == 3: + include "window_info_cef3.pyx" + include "process_message_utils.pyx" + include "v8context_handler_cef3.pyx" + include "v8function_handler_cef3.pyx" + include "javascript_callback_cef3.pyx" + include "python_callback_cef3.pyx" + include "lifespan_handler_cef3.pyx" + include "display_handler_cef3.pyx" + include "keyboard_handler_cef3.pyx" + include "web_plugin_info_cef3.pyx" + include "request_cef3.pyx" + include "request_handler_cef3.pyx" + include "cookie_cef3.pyx" + include "string_visitor_cef3.pyx" + include "load_handler_cef3.pyx" + include "network_error_cef3.pyx" + include "browser_process_handler_cef3.pyx" + include "paint_buffer_cef3.pyx" + include "render_handler_cef3.pyx" + include "callback_cef3.pyx" + include "resource_handler_cef3.pyx" + include "response_cef3.pyx" + include "web_request_cef3.pyx" + include "command_line.pyx" + include "app.pyx" + include "javascript_dialog_handler.pyx" + +# ----------------------------------------------------------------------------- +# Utility functions to provide settings to the C++ browser process code. + +cdef public void cefpython_GetDebugOptions( + cpp_bool* debug, + cpp_string* debugFile + ) except * with gil: + # Called from subprocess/cefpython_app.cpp -> CefPythonApp constructor. + cdef cpp_string cppString = g_debugFile + try: + debug[0] = bool(g_debug) + debugFile.assign(cppString) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool ApplicationSettings_GetBool(const char* key + ) except * with gil: + # Called from client_handler/client_handler.cpp for example + cdef py_string pyKey = CharToPyString(key) + if pyKey in g_applicationSettings: + return bool(g_applicationSettings[pyKey]) + return False + +cdef public cpp_bool ApplicationSettings_GetBoolFromDict(const char* key1, + const char* key2) except * with gil: + cdef py_string pyKey1 = CharToPyString(key1) + cdef py_string pyKey2 = CharToPyString(key2) + cdef object dictValue # Yet to be checked whether it is `dict` + if pyKey1 in g_applicationSettings: + dictValue = g_applicationSettings[pyKey1] + if type(dictValue) != dict: + return False + if pyKey2 in dictValue: + return bool(dictValue[pyKey2]) + return False + +cdef public cpp_string ApplicationSettings_GetString(const char* key + ) except * with gil: + cdef py_string pyKey = CharToPyString(key) + cdef cpp_string cppString + if pyKey in g_applicationSettings: + cppString = AnyToPyString(g_applicationSettings[pyKey]) + return cppString + +cdef public int CommandLineSwitches_GetInt(const char* key) except * with gil: + cdef py_string pyKey = CharToPyString(key) + if pyKey in g_commandLineSwitches: + return int(g_commandLineSwitches[pyKey]) + return 0 + +# ----------------------------------------------------------------------------- + +# If you've built custom binaries with tcmalloc hook enabled on +# Linux, then do not to run any of the CEF code until Initialize() +# is called. See Issue 73 in the CEF Python Issue Tracker. + +def Initialize(applicationSettings=None, commandLineSwitches=None): + if not applicationSettings: + applicationSettings = {} + # Debug settings need to be set before Debug() is called + # and before the CefPythonApp class is instantiated. + global g_debug + global g_debugFile + if "debug" in applicationSettings: + g_debug = bool(applicationSettings["debug"]) + if "log_file" in applicationSettings: + g_debugFile = applicationSettings["log_file"] + + Debug("Initialize() called") + + # Mac initialization. Need to call NSApplication.sharedApplication() + # and do NSApplication methods swizzling to implement + # CrAppControlProtocol. See Issue 156. + IF UNAME_SYSNAME == "Darwin": + MacInitialize() + + # ------------------------------------------------------------------------- + # CEF Python only options - default values + + if "debug" not in applicationSettings: + applicationSettings["debug"] = False + if "string_encoding" not in applicationSettings: + applicationSettings["string_encoding"] = "utf-8" + if "unique_request_context_per_browser" not in applicationSettings: + applicationSettings["unique_request_context_per_browser"] = False + if "downloads_enabled" not in applicationSettings: + applicationSettings["downloads_enabled"] = True + if "remote_debugging_port" not in applicationSettings: + applicationSettings["remote_debugging_port"] = 0 + if "auto_zooming" not in applicationSettings: + IF UNAME_SYSNAME == "Windows": + if DpiAware.IsProcessDpiAware(): + applicationSettings["auto_zooming"] = "system_dpi" + + # Mouse context menu + if "context_menu" not in applicationSettings: + applicationSettings["context_menu"] = {} + menuItems = ["enabled", "navigation", "print", "view_source",\ + "external_browser", "devtools"] + for item in menuItems: + if item not in applicationSettings["context_menu"]: + applicationSettings["context_menu"][item] = True + + # Remote debugging port. If value is 0 we will generate a random + # port. To disable remote debugging set value to -1. + if applicationSettings["remote_debugging_port"] == 0: + # Generate a random port. + applicationSettings["remote_debugging_port"] =\ + random.randint(49152, 65535) + elif applicationSettings["remote_debugging_port"] == -1: + # Disable remote debugging + applicationSettings["remote_debugging_port"] = 0 + + # ------------------------------------------------------------------------- + + # CEF options - default values. + if not "multi_threaded_message_loop" in applicationSettings: + applicationSettings["multi_threaded_message_loop"] = False + IF CEF_VERSION == 3: + if not "single_process" in applicationSettings: + applicationSettings["single_process"] = False + + cdef CefRefPtr[CefApp] cefApp + + IF CEF_VERSION == 3: + cefApp = new CefPythonApp() + IF UNAME_SYSNAME == "Windows": + cdef HINSTANCE hInstance = GetModuleHandle(NULL) + cdef CefMainArgs cefMainArgs = CefMainArgs(hInstance) + ELIF UNAME_SYSNAME == "Linux": + # TODO: use the CefMainArgs(int argc, char** argv) constructor. + cdef CefMainArgs cefMainArgs + ELIF UNAME_SYSNAME == "Darwin": + # TODO: use the CefMainArgs(int argc, char** argv) constructor. + cdef CefMainArgs cefMainArgs + cdef int exitCode = 1 + with nogil: + exitCode = CefExecuteProcess(cefMainArgs, cefApp) + Debug("CefExecuteProcess(): exitCode = %s" % exitCode) + if exitCode >= 0: + sys.exit(exitCode) + + # Make a copy as applicationSettings is a reference only + # that might get destroyed later. + global g_applicationSettings + for key in applicationSettings: + g_applicationSettings[key] = copy.deepcopy(applicationSettings[key]) + + cdef CefSettings cefApplicationSettings + SetApplicationSettings(applicationSettings, &cefApplicationSettings) + + if commandLineSwitches: + # Make a copy as commandLineSwitches is a reference only + # that might get destroyed later. + global g_commandLineSwitches + for key in commandLineSwitches: + g_commandLineSwitches[key] = copy.deepcopy( + commandLineSwitches[key]) + + Debug("CefInitialize()") + cdef cpp_bool ret + IF CEF_VERSION == 1: + with nogil: + ret = CefInitialize(cefApplicationSettings, cefApp) + ELIF CEF_VERSION == 3: + with nogil: + ret = CefInitialize(cefMainArgs, cefApplicationSettings, cefApp) + + if not ret: + Debug("CefInitialize() failed") + return ret + +def CreateBrowserSync(windowInfo, browserSettings, navigateUrl, requestContext=None): + Debug("CreateBrowserSync() called") + assert IsThread(TID_UI), ( + "cefpython.CreateBrowserSync() may only be called on the UI thread") + + if not isinstance(windowInfo, WindowInfo): + raise Exception("CreateBrowserSync() failed: windowInfo: invalid object") + + cdef CefBrowserSettings cefBrowserSettings + SetBrowserSettings(browserSettings, &cefBrowserSettings) + + cdef CefWindowInfo cefWindowInfo + SetCefWindowInfo(cefWindowInfo, windowInfo) + + navigateUrl = GetNavigateUrl(navigateUrl) + Debug("navigateUrl: %s" % navigateUrl) + cdef CefString cefNavigateUrl + PyToCefString(navigateUrl, cefNavigateUrl) + + Debug("CefBrowser::CreateBrowserSync()") + cdef CefRefPtr[ClientHandler] clientHandler =\ + new ClientHandler() + cdef CefRefPtr[CefBrowser] cefBrowser + + # Request context - part 1/2. + createSharedRequestContext = bool(not g_sharedRequestContext.get()) + cdef CefRefPtr[CefRequestContext] cefRequestContext + cdef CefRefPtr[RequestContextHandler] requestContextHandler =\ + new RequestContextHandler(\ + cefBrowser) + if g_applicationSettings["unique_request_context_per_browser"]: + cefRequestContext = CefRequestContext_CreateContext(\ + requestContextHandler) + else: + if createSharedRequestContext: + cefRequestContext = CefRequestContext_CreateContext(\ + \ + requestContextHandler) + g_sharedRequestContext.Assign(cefRequestContext.get()) + else: + cefRequestContext.Assign(g_sharedRequestContext.get()) + + # CEF browser creation. + with nogil: + cefBrowser = cef_browser_static.CreateBrowserSync( + cefWindowInfo, clientHandler, + cefNavigateUrl, cefBrowserSettings, + cefRequestContext) + + if cefBrowser == NULL or not cefBrowser.get(): + Debug("CefBrowser::CreateBrowserSync() failed") + return None + else: + Debug("CefBrowser::CreateBrowserSync() succeeded") + + # Request context - part 2/2. + if g_applicationSettings["unique_request_context_per_browser"]: + requestContextHandler.get().SetBrowser(cefBrowser) + else: + if createSharedRequestContext: + requestContextHandler.get().SetBrowser(cefBrowser) + + cdef PyBrowser pyBrowser = GetPyBrowser(cefBrowser) + pyBrowser.SetUserData("__outerWindowHandle", int(windowInfo.parentWindowHandle)) + + # IF CEF_VERSION == 3: + # Test whether process message sent before renderer thread is created + # will be delivered - OK. + # Debug("Sending 'CreateBrowserSync() done' message to the Renderer") + # pyBrowser.SendProcessMessage(cef_types.PID_RENDERER, + # "CreateBrowserSync() done") + + return pyBrowser + +def MessageLoop(): + Debug("MessageLoop()") + with nogil: + CefRunMessageLoop() + +def MessageLoopWork(): + # Perform a single iteration of CEF message loop processing. + # This function is used to integrate the CEF message loop + # into an existing application message loop. + + # Anything that can block for a significant amount of time + # and is thread-safe should release the GIL: + # https://groups.google.com/d/msg/cython-users/jcvjpSOZPp0/KHpUEX8IhnAJ + # GIL must be released here otherwise we will get dead lock + # when calling from c++ to python. + + with nogil: + CefDoMessageLoopWork(); + +def SingleMessageLoop(): + # @deprecated, use MessageLoopWork() instead + MessageLoopWork() + +def QuitMessageLoop(): + Debug("QuitMessageLoop()") + with nogil: + CefQuitMessageLoop() + +def Shutdown(): + if g_sharedRequestContext.get(): + # A similar release is done in RemovePyBrowser and CloseBrowser. + # This one is probably redundant. Additional testing should be done. + Debug("Shutdown: releasing shared request context") + g_sharedRequestContext.Assign(NULL) + Debug("Shutdown()") + with nogil: + CefShutdown() + +def SetOsModalLoop(py_bool modalLoop): + cdef cpp_bool cefModalLoop = bool(modalLoop) + with nogil: + CefSetOSModalLoop(cefModalLoop) + +cpdef py_void SetGlobalClientCallback(py_string name, object callback): + global g_globalClientCallbacks + if name in ["OnCertificateError", "OnBeforePluginLoad", "OnAfterCreated"]: + g_globalClientCallbacks[name] = callback + else: + raise Exception("SetGlobalClientCallback() failed: " \ + "invalid callback name = %s" % name) + +cpdef object GetGlobalClientCallback(py_string name): + global g_globalClientCallbacks + if name in g_globalClientCallbacks: + return g_globalClientCallbacks[name] + else: + return None + diff --git a/cefpython/command_line.pyx b/cefpython/command_line.pyx new file mode 100644 index 00000000..90b3026d --- /dev/null +++ b/cefpython/command_line.pyx @@ -0,0 +1,65 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef void AppendSwitchesToCommandLine( + CefRefPtr[CefCommandLine] cefCommandLine, + dict switches + ) except * with gil: + # Called from: + # 1. App_OnBeforeCommandLineProcessing_BrowserProcess() + # 2. BrowserProcessHandler_OnRenderProcessThreadCreated() + cdef PyCommandLine pyCommandLine = CreatePyCommandLine(cefCommandLine) + cdef py_string switch + cdef py_string value + for switch, value in switches.iteritems(): + if not isinstance(switch, basestring) or switch[0] == '-': + Debug("Invalid command line switch: %s" % switch) + continue + if value: + if pyCommandLine.HasSwitch(switch)\ + and value == pyCommandLine.GetSwitchValue(switch): + Debug("Switch already set, ignoring: %s" % switch) + else: + pyCommandLine.AppendSwitchWithValue(switch, value) + else: + if pyCommandLine.HasSwitch(switch): + Debug("Switch already set, ignoring: %s" % switch) + else: + pyCommandLine.AppendSwitch(switch) + +cdef PyCommandLine CreatePyCommandLine( + CefRefPtr[CefCommandLine] cefCommandLine): + cdef PyCommandLine pyCommandLine = PyCommandLine() + pyCommandLine.cefCommandLine = cefCommandLine + return pyCommandLine + +cdef class PyCommandLine: + cdef CefRefPtr[CefCommandLine] cefCommandLine + + cdef py_void AppendSwitch(self, py_string switch): + cdef CefString cefSwitch + cefSwitch = PyToCefStringValue(switch) + self.cefCommandLine.get().AppendSwitch(cefSwitch) + + cdef py_void AppendSwitchWithValue(self, py_string switch, py_string value): + cdef CefString cefSwitch + cdef CefString cefValue + cefSwitch = PyToCefStringValue(switch) + cefValue = PyToCefStringValue(value) + self.cefCommandLine.get().AppendSwitchWithValue(cefSwitch, cefValue) + + cdef py_string GetCommandLineString(self): + return CefToPyString(self.cefCommandLine.get().GetCommandLineString()) + + cdef py_bool HasSwitch(self, py_string switch): + cdef CefString cefSwitch + cefSwitch = PyToCefStringValue(switch) + return self.cefCommandLine.get().HasSwitch(cefSwitch) + + cdef py_string GetSwitchValue(self, py_string switch): + cdef CefString cefValue + cdef CefString cefSwitch + cefSwitch = PyToCefStringValue(switch) + cefValue = self.cefCommandLine.get().GetSwitchValue(cefSwitch) + return CefToPyString(cefValue) diff --git a/cefpython/content_filter.pyx b/cefpython/content_filter.pyx new file mode 100644 index 00000000..6d9da98f --- /dev/null +++ b/cefpython/content_filter.pyx @@ -0,0 +1,117 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# TODO: fix CefContentFilter memory corruption and restore weakrefs +# for PyContentFilter object. Right now getting memory corruption +# when CefRefPtr[CefWebURLRequest] is released after the request +# is completed. The memory corruption manifests itself with the +# "Segmentation Fault" error message or the strange "C function +# name could not be determined in the current C stack frame". +# See this topic on cython-users group: +# https://groups.google.com/d/topic/cython-users/FJZwHhqaCSI/discussion +# After CefWebURLRequest memory corruption is fixed restore weakrefs: +# 1. cdef object g_pyWebRequests = weakref.WeakValueDictionary() +# 2. Add property "cdef object __weakref__" in PyContentFilter +# When using normal dictionary for g_pyWebRequest then the memory +# corruption doesn't occur, but the PyContentFilter and CefContentFilter +# objects are never released, thus you have memory leaks, for now +# there is no other solution. See this topic on the CEF Forum: +# http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10711 +cdef object g_contentFilters = {} +cdef int g_contentFilterMaxId = 0 + +# ------------------------------------------------------------------------------ +# PyContentFilter +# ------------------------------------------------------------------------------ + +cdef PyContentFilter GetPyContentFilter(int contentFilterId): + global g_contentFilters + if contentFilterId in g_contentFilters: + return g_contentFilters[contentFilterId] + return None + +cdef class PyContentFilter: + # cdef object __weakref__ # see g_contentFilters + cdef int contentFilterId + cdef CefRefPtr[CefContentFilter] cefContentFilter + cdef object handler + + def __init__(self): + global g_contentFilterMaxId + global g_contentFilters + g_contentFilterMaxId += 1 + self.contentFilterId = g_contentFilterMaxId + g_contentFilters[self.contentFilterId] = self + self.cefContentFilter = ( + new ContentFilterHandler( + self.contentFilterId)) + + def SetHandler(self, handler): + assert handler, "ContentFilterHandler is empty" + has_OnData = hasattr(handler, "OnData") and ( + callable(getattr(handler, "OnData"))) + has_OnDrain = hasattr(handler, "OnDrain") and ( + callable(getattr(handler, "OnDrain"))) + assert has_OnData, "ContentFilterHandler is missing OnData() method" + assert has_OnDrain, "ContentFilterHandler is missing OnDrain() method" + self.handler = handler + + def HasHandler(self): + return bool(self.handler) + + cdef object GetCallback(self, str funcName): + if not self.handler: + return None + if hasattr(self.handler, funcName) and ( + callable(getattr(self.handler, funcName))): + return getattr(self.handler, funcName) + + cdef CefRefPtr[CefContentFilter] GetCefContentFilter(self) except *: + return self.cefContentFilter + +# ------------------------------------------------------------------------------ +# C++ ContentFilterHandler +# ------------------------------------------------------------------------------ + +cdef public void ContentFilterHandler_ProcessData( + int contentFilterId, + const void* data, + int data_size, + CefRefPtr[CefStreamReader]& substitute_data + ) except * with gil: + cdef PyContentFilter contentFilter + cdef object callback + cdef PyStreamReader pyStreamReader + try: + contentFilter = GetPyContentFilter(contentFilterId) + if contentFilter: + callback = contentFilter.GetCallback("OnData") + if callback: + pyStreamReader = PyStreamReader() + callback(VoidPtrToString(data, data_size), pyStreamReader) + if pyStreamReader.HasCefStreamReader(): + substitute_data.swap(pyStreamReader.GetCefStreamReader()) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void ContentFilterHandler_Drain( + int contentFilterId, + CefRefPtr[CefStreamReader]& remainder + ) except * with gil: + cdef PyContentFilter contentFilter + cdef object callback + cdef PyStreamReader pyStreamReader + try: + contentFilter = GetPyContentFilter(contentFilterId) + if contentFilter: + callback = contentFilter.GetCallback("OnDrain") + if callback: + pyStreamReader = PyStreamReader() + callback(pyStreamReader) + if pyStreamReader.HasCefStreamReader(): + remainder.swap(pyStreamReader.GetCefStreamReader()) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/cookie_cef1.pyx b/cefpython/cookie_cef1.pyx new file mode 100644 index 00000000..5480b6c7 --- /dev/null +++ b/cefpython/cookie_cef1.pyx @@ -0,0 +1,326 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# ------------------------------------------------------------------------------ +# Tests +# ------------------------------------------------------------------------------ + +#cdef Cookie cookie = Cookie() +#cookie.SetName("asd1") +#print("cookie.cefCookie: %s" % cookie.cefCookie) +#print("cookie.GetName(): %s" % cookie.GetName()) +#print("cookie.GetCreation(): %s" % cookie.GetCreation()) +#cookie.SetCreation(datetime.datetime(2013,5,23)) +#print("cookie.GetCreation(): %s" % cookie.GetCreation()) +#print("cookie: %s" % cookie.Get()) + +# ------------------------------------------------------------------------------ +# Globals +# ------------------------------------------------------------------------------ + +cdef PyCookieManager g_globalCookieManager = None +# See StoreUserCookieVisitor(). +cdef object g_userCookieVisitors = weakref.WeakValueDictionary() +cdef int g_userCookieVisitorMaxId = 0 + +# ------------------------------------------------------------------------------ +# Cookie +# ------------------------------------------------------------------------------ + +ctypedef Cookie PyCookie + +cdef PyCookie CreatePyCookie(CefCookie cefCookie): + cdef PyCookie pyCookie = Cookie() + pyCookie.cefCookie = cefCookie + return pyCookie + +cdef class Cookie: + cdef CefCookie cefCookie + + cpdef py_void Set(self, dict cookie): + for key in cookie: + if key == "name": + self.SetName(cookie[key]) + elif key == "value": + self.SetValue(cookie[key]) + elif key == "domain": + self.SetDomain(cookie[key]) + elif key == "path": + self.SetPath(cookie[key]) + elif key == "secure": + self.SetSecure(cookie[key]) + elif key == "httpOnly": + self.SetHttpOnly(cookie[key]) + elif key == "creation": + self.SetCreation(cookie[key]) + elif key == "lastAccess": + self.SetLastAccess(cookie[key]) + elif key == "hasExpires": + self.SetHasExpires(cookie[key]) + elif key == "expires": + self.SetExpires(cookie[key]) + else: + raise Exception("Invalid key: %s" % key) + + cpdef dict Get(self): + return { + "name": self.GetName(), + "value": self.GetValue(), + "domain": self.GetDomain(), + "path": self.GetPath(), + "secure": self.GetSecure(), + "httpOnly": self.GetHttpOnly(), + "creation": self.GetCreation(), + "lastAccess": self.GetLastAccess(), + "hasExpires": self.GetHasExpires(), + "expires": self.GetExpires(), + } + + cpdef py_void SetName(self, py_string name): + # This works: + # | CefString(&self.cefCookie.name).FromString(name) + # This does not work: + # | cdef CefString cefString = CefString(&self.cefCookie.name) + # | PyToCefString(name, cefString) + # Because it's a Copy Constructor, it does not reference the + # same underlying cef_string_t, instead it copies the value. + # "T a(b)" - direct initialization (not supported by cython) + # "T a = b" - copy initialization + # But this works: + # | cdef CefString* cefString = new CefString(&self.cefCookie.name) + # | PyToCefStringPointer(name, cefString) + # | del cefString + # Solution: use Attach() method to pass reference to cef_string_t. + cdef CefString cefString + cefString.Attach(&self.cefCookie.name, False) + PyToCefString(name, cefString) + + cpdef str GetName(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.name, False) + return CefToPyString(cefString) + + cpdef py_void SetValue(self, py_string value): + cdef CefString cefString + cefString.Attach(&self.cefCookie.value, False) + PyToCefString(value, cefString) + + cpdef str GetValue(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.value, False) + return CefToPyString(cefString) + + cpdef py_void SetDomain(self, py_string domain): + cdef CefString cefString + cefString.Attach(&self.cefCookie.domain, False) + PyToCefString(domain, cefString) + + cpdef str GetDomain(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.domain, False) + return CefToPyString(cefString) + + cpdef py_void SetPath(self, py_string path): + cdef CefString cefString + cefString.Attach(&self.cefCookie.path, False) + PyToCefString(path, cefString) + + cpdef str GetPath(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.path, False) + return CefToPyString(cefString) + + cpdef py_void SetSecure(self, py_bool secure): + # Need to wrap it with bool() to get rid of the C++ compiler + # warnings: "cefpython.cpp(24740) : warning C4800: 'int' : + # forcing value to bool 'true' or 'false' (performance warning)". + self.cefCookie.secure = bool(secure) + + cpdef py_bool GetSecure(self): + return self.cefCookie.secure + + cpdef py_void SetHttpOnly(self, py_bool httpOnly): + self.cefCookie.httponly = bool(httpOnly) + + cpdef py_bool GetHttpOnly(self): + return self.cefCookie.httponly + + cpdef py_void SetCreation(self, object creation): + DatetimeToCefTimeT(creation, self.cefCookie.creation) + + cpdef object GetCreation(self): + return CefTimeTToDatetime(self.cefCookie.creation) + + cpdef py_void SetLastAccess(self, object lastAccess): + DatetimeToCefTimeT(lastAccess, self.cefCookie.last_access) + + cpdef object GetLastAccess(self): + return CefTimeTToDatetime(self.cefCookie.last_access) + + cpdef py_void SetHasExpires(self, py_bool hasExpires): + self.cefCookie.has_expires = bool(hasExpires) + + cpdef py_bool GetHasExpires(self): + return self.cefCookie.has_expires + + cpdef py_void SetExpires(self, object expires): + DatetimeToCefTimeT(expires, self.cefCookie.expires) + + cpdef object GetExpires(self): + return CefTimeTToDatetime(self.cefCookie.expires) + +# ------------------------------------------------------------------------------ +# CookieManager +# ------------------------------------------------------------------------------ + +class CookieManager: + @staticmethod + def GetGlobalManager(): + global g_globalCookieManager + cdef CefRefPtr[CefCookieManager] cefCookieManager + if not g_globalCookieManager: + cefCookieManager = CefCookieManager_GetGlobalManager() + g_globalCookieManager = CreatePyCookieManager(cefCookieManager) + return g_globalCookieManager + + @staticmethod + def CreateManager(py_string path, py_bool persistSessionCookies=False): + cdef CefRefPtr[CefCookieManager] cefCookieManager + IF CEF_VERSION == 1: + cefCookieManager = CefCookieManager_CreateManager( + PyToCefStringValue(path)) + ELIF CEF_VERSION == 3: + cefCookieManager = CefCookieManager_CreateManager( + PyToCefStringValue(path), bool(persistSessionCookies)) + if cefCookieManager != NULL and cefCookieManager.get(): + return CreatePyCookieManager(cefCookieManager) + return None + +# ------------------------------------------------------------------------------ +# PyCookieManager +# ------------------------------------------------------------------------------ + +cdef PyCookieManager CreatePyCookieManager( + CefRefPtr[CefCookieManager] cefCookieManager): + cdef PyCookieManager pyCookieManager = PyCookieManager() + pyCookieManager.cefCookieManager = cefCookieManager + return pyCookieManager + +cdef class PyCookieManager: + cdef CefRefPtr[CefCookieManager] cefCookieManager + + cpdef py_void SetSupportedSchemes(self, list schemes): + cdef cpp_vector[CefString] schemesVector + for scheme in schemes: + schemesVector.push_back(PyToCefStringValue(scheme)) + self.cefCookieManager.get().SetSupportedSchemes(schemesVector) + + cdef py_void ValidateUserCookieVisitor(self, object userCookieVisitor): + if userCookieVisitor and hasattr(userCookieVisitor, "Visit") and \ + callable(getattr(userCookieVisitor, "Visit")): + return + raise Exception("CookieVisitor object is missing Visit() method") + + cpdef py_bool VisitAllCookies(self, object userCookieVisitor): + self.ValidateUserCookieVisitor(userCookieVisitor) + cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor) + cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = ( + new CookieVisitor( + cookieVisitorId)) + return self.cefCookieManager.get().VisitAllCookies( + cefCookieVisitor) + + cpdef py_bool VisitUrlCookies(self, py_string url, + py_bool includeHttpOnly, object userCookieVisitor): + self.ValidateUserCookieVisitor(userCookieVisitor) + cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor) + cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = ( + new CookieVisitor( + cookieVisitorId)) + return self.cefCookieManager.get().VisitUrlCookies( + PyToCefStringValue(url), bool(includeHttpOnly), + cefCookieVisitor) + + cpdef py_void SetCookie(self, py_string url, PyCookie cookie): + assert isinstance(cookie, Cookie), "cookie object is invalid" + CefPostTask(TID_IO, NewCefRunnableMethod(self.cefCookieManager.get(), + &cef_cookie_manager_namespace.SetCookie, + PyToCefStringValue(url), cookie.cefCookie)) + + cpdef py_void DeleteCookies(self, py_string url, py_string cookie_name): + CefPostTask(TID_IO, NewCefRunnableMethod(self.cefCookieManager.get(), + &cef_cookie_manager_namespace.DeleteCookies, + PyToCefStringValue(url), PyToCefStringValue(cookie_name))) + + cpdef py_bool SetStoragePath(self, py_string path, + py_bool persistSessionCookies=False): + IF CEF_VERSION == 1: + return self.cefCookieManager.get().SetStoragePath( + PyToCefStringValue(path)) + ELIF CEF_VERSION == 3: + return self.cefCookieManager.get().SetStoragePath( + PyToCefStringValue(path), bool(persistSessionCookies)) + +# ------------------------------------------------------------------------------ +# PyCookieVisitor +# ------------------------------------------------------------------------------ + +cdef int StoreUserCookieVisitor(object userCookieVisitor) except *: + global g_userCookieVisitorMaxId + global g_userCookieVisitors + g_userCookieVisitorMaxId += 1 + g_userCookieVisitors[g_userCookieVisitorMaxId] = userCookieVisitor + return g_userCookieVisitorMaxId + +cdef PyCookieVisitor GetPyCookieVisitor(int cookieVisitorId): + global g_userCookieVisitors + cdef object userCookieVisitor + cdef PyCookieVisitor pyCookieVisitor + if cookieVisitorId in g_userCookieVisitors: + userCookieVisitor = g_userCookieVisitors[cookieVisitorId] + pyCookieVisitor = PyCookieVisitor(userCookieVisitor) + return pyCookieVisitor + +cdef class PyCookieVisitor: + cdef object userCookieVisitor + + def __init__(self, object userCookieVisitor): + self.userCookieVisitor = userCookieVisitor + + cdef object GetCallback(self, str funcName): + if self.userCookieVisitor and ( + hasattr(self.userCookieVisitor, funcName) and ( + callable(getattr(self.userCookieVisitor, funcName)))): + return getattr(self.userCookieVisitor, funcName) + +# ------------------------------------------------------------------------------ +# C++ CookieVisitor +# ------------------------------------------------------------------------------ + +cdef public cpp_bool CookieVisitor_Visit( + int cookieVisitorId, + const CefCookie& cookie, + int count, + int total, + cpp_bool& deleteCookie + ) except * with gil: + cdef PyCookieVisitor pyCookieVisitor + cdef object callback + cdef py_bool ret + cdef PyCookie pyCookie + cdef list pyDeleteCookie = [False] + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyCookieVisitor = GetPyCookieVisitor(cookieVisitorId) + pyCookie = CreatePyCookie(cookie) + if pyCookieVisitor: + callback = pyCookieVisitor.GetCallback("Visit") + if callback: + ret = callback(pyCookie, count, total, pyDeleteCookie) + (&deleteCookie)[0] = bool(pyDeleteCookie[0]) + return bool(ret) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/cookie_cef3.pyx b/cefpython/cookie_cef3.pyx new file mode 100644 index 00000000..d12b1454 --- /dev/null +++ b/cefpython/cookie_cef3.pyx @@ -0,0 +1,319 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# ------------------------------------------------------------------------------ +# Tests +# ------------------------------------------------------------------------------ + +#cdef Cookie cookie = Cookie() +#cookie.SetName("asd1") +#print("cookie.cefCookie: %s" % cookie.cefCookie) +#print("cookie.GetName(): %s" % cookie.GetName()) +#print("cookie.GetCreation(): %s" % cookie.GetCreation()) +#cookie.SetCreation(datetime.datetime(2013,5,23)) +#print("cookie.GetCreation(): %s" % cookie.GetCreation()) +#print("cookie: %s" % cookie.Get()) + +# ------------------------------------------------------------------------------ +# Globals +# ------------------------------------------------------------------------------ + +cdef PyCookieManager g_globalCookieManager = None +# See StoreUserCookieVisitor(). +cdef object g_userCookieVisitors = weakref.WeakValueDictionary() +cdef int g_userCookieVisitorMaxId = 0 + +# ------------------------------------------------------------------------------ +# Cookie +# ------------------------------------------------------------------------------ + +ctypedef Cookie PyCookie + +cdef PyCookie CreatePyCookie(CefCookie cefCookie): + cdef PyCookie pyCookie = Cookie() + pyCookie.cefCookie = cefCookie + return pyCookie + +cdef class Cookie: + cdef CefCookie cefCookie + + cpdef py_void Set(self, dict cookie): + for key in cookie: + if key == "name": + self.SetName(cookie[key]) + elif key == "value": + self.SetValue(cookie[key]) + elif key == "domain": + self.SetDomain(cookie[key]) + elif key == "path": + self.SetPath(cookie[key]) + elif key == "secure": + self.SetSecure(cookie[key]) + elif key == "httpOnly": + self.SetHttpOnly(cookie[key]) + elif key == "creation": + self.SetCreation(cookie[key]) + elif key == "lastAccess": + self.SetLastAccess(cookie[key]) + elif key == "hasExpires": + self.SetHasExpires(cookie[key]) + elif key == "expires": + self.SetExpires(cookie[key]) + else: + raise Exception("Invalid key: %s" % key) + + cpdef dict Get(self): + return { + "name": self.GetName(), + "value": self.GetValue(), + "domain": self.GetDomain(), + "path": self.GetPath(), + "secure": self.GetSecure(), + "httpOnly": self.GetHttpOnly(), + "creation": self.GetCreation(), + "lastAccess": self.GetLastAccess(), + "hasExpires": self.GetHasExpires(), + "expires": self.GetExpires(), + } + + cpdef py_void SetName(self, py_string name): + # This works: + # | CefString(&self.cefCookie.name).FromString(name) + # This does not work: + # | cdef CefString cefString = CefString(&self.cefCookie.name) + # | PyToCefString(name, cefString) + # Because it's a Copy Constructor, it does not reference the + # same underlying cef_string_t, instead it copies the value. + # "T a(b)" - direct initialization (not supported by cython) + # "T a = b" - copy initialization + # But this works: + # | cdef CefString* cefString = new CefString(&self.cefCookie.name) + # | PyToCefStringPointer(name, cefString) + # | del cefString + # Solution: use Attach() method to pass reference to cef_string_t. + cdef CefString cefString + cefString.Attach(&self.cefCookie.name, False) + PyToCefString(name, cefString) + + cpdef str GetName(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.name, False) + return CefToPyString(cefString) + + cpdef py_void SetValue(self, py_string value): + cdef CefString cefString + cefString.Attach(&self.cefCookie.value, False) + PyToCefString(value, cefString) + + cpdef str GetValue(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.value, False) + return CefToPyString(cefString) + + cpdef py_void SetDomain(self, py_string domain): + cdef CefString cefString + cefString.Attach(&self.cefCookie.domain, False) + PyToCefString(domain, cefString) + + cpdef str GetDomain(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.domain, False) + return CefToPyString(cefString) + + cpdef py_void SetPath(self, py_string path): + cdef CefString cefString + cefString.Attach(&self.cefCookie.path, False) + PyToCefString(path, cefString) + + cpdef str GetPath(self): + cdef CefString cefString + cefString.Attach(&self.cefCookie.path, False) + return CefToPyString(cefString) + + cpdef py_void SetSecure(self, py_bool secure): + # Need to wrap it with bool() to get rid of the C++ compiler + # warnings: "cefpython.cpp(24740) : warning C4800: 'int' : + # forcing value to bool 'true' or 'false' (performance warning)". + self.cefCookie.secure = bool(secure) + + cpdef py_bool GetSecure(self): + return self.cefCookie.secure + + cpdef py_void SetHttpOnly(self, py_bool httpOnly): + self.cefCookie.httponly = bool(httpOnly) + + cpdef py_bool GetHttpOnly(self): + return self.cefCookie.httponly + + cpdef py_void SetCreation(self, object creation): + DatetimeToCefTimeT(creation, self.cefCookie.creation) + + cpdef object GetCreation(self): + return CefTimeTToDatetime(self.cefCookie.creation) + + cpdef py_void SetLastAccess(self, object lastAccess): + DatetimeToCefTimeT(lastAccess, self.cefCookie.last_access) + + cpdef object GetLastAccess(self): + return CefTimeTToDatetime(self.cefCookie.last_access) + + cpdef py_void SetHasExpires(self, py_bool hasExpires): + self.cefCookie.has_expires = bool(hasExpires) + + cpdef py_bool GetHasExpires(self): + return self.cefCookie.has_expires + + cpdef py_void SetExpires(self, object expires): + DatetimeToCefTimeT(expires, self.cefCookie.expires) + + cpdef object GetExpires(self): + return CefTimeTToDatetime(self.cefCookie.expires) + +# ------------------------------------------------------------------------------ +# CookieManager +# ------------------------------------------------------------------------------ + +class CookieManager: + @staticmethod + def GetGlobalManager(): + global g_globalCookieManager + cdef CefRefPtr[CefCookieManager] cefCookieManager + if not g_globalCookieManager: + cefCookieManager = CefCookieManager_GetGlobalManager() + g_globalCookieManager = CreatePyCookieManager(cefCookieManager) + return g_globalCookieManager + + @staticmethod + def CreateManager(py_string path, py_bool persistSessionCookies=False): + cdef CefRefPtr[CefCookieManager] cefCookieManager + cefCookieManager = CefCookieManager_CreateManager( + PyToCefStringValue(path), bool(persistSessionCookies)) + if cefCookieManager != NULL and cefCookieManager.get(): + return CreatePyCookieManager(cefCookieManager) + return None + +# ------------------------------------------------------------------------------ +# PyCookieManager +# ------------------------------------------------------------------------------ + +cdef PyCookieManager CreatePyCookieManager( + CefRefPtr[CefCookieManager] cefCookieManager): + cdef PyCookieManager pyCookieManager = PyCookieManager() + pyCookieManager.cefCookieManager = cefCookieManager + return pyCookieManager + +cdef class PyCookieManager: + cdef CefRefPtr[CefCookieManager] cefCookieManager + + cpdef py_void SetSupportedSchemes(self, list schemes): + cdef cpp_vector[CefString] schemesVector + for scheme in schemes: + schemesVector.push_back(PyToCefStringValue(scheme)) + self.cefCookieManager.get().SetSupportedSchemes(schemesVector) + + cdef py_void ValidateUserCookieVisitor(self, object userCookieVisitor): + if userCookieVisitor and hasattr(userCookieVisitor, "Visit") and ( + callable(getattr(userCookieVisitor, "Visit"))): + # OK. + return + raise Exception("CookieVisitor object is missing Visit() method") + + cpdef py_bool VisitAllCookies(self, object userCookieVisitor): + self.ValidateUserCookieVisitor(userCookieVisitor) + cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor) + cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = ( + new CookieVisitor( + cookieVisitorId)) + return self.cefCookieManager.get().VisitAllCookies( + cefCookieVisitor) + + cpdef py_bool VisitUrlCookies(self, py_string url, + py_bool includeHttpOnly, object userCookieVisitor): + self.ValidateUserCookieVisitor(userCookieVisitor) + cdef int cookieVisitorId = StoreUserCookieVisitor(userCookieVisitor) + cdef CefRefPtr[CefCookieVisitor] cefCookieVisitor = ( + new CookieVisitor( + cookieVisitorId)) + return self.cefCookieManager.get().VisitUrlCookies( + PyToCefStringValue(url), bool(includeHttpOnly), + cefCookieVisitor) + + cpdef py_void SetCookie(self, py_string url, PyCookie cookie): + assert isinstance(cookie, Cookie), "cookie object is invalid" + CefPostTask(TID_IO, NewCefRunnableMethod(self.cefCookieManager.get(), + &cef_cookie_manager_namespace.SetCookie, + PyToCefStringValue(url), cookie.cefCookie)) + + cpdef py_void DeleteCookies(self, py_string url, py_string cookie_name): + CefPostTask(TID_IO, NewCefRunnableMethod(self.cefCookieManager.get(), + &cef_cookie_manager_namespace.DeleteCookies, + PyToCefStringValue(url), PyToCefStringValue(cookie_name))) + + cpdef py_bool SetStoragePath(self, py_string path, + py_bool persistSessionCookies=False): + return self.cefCookieManager.get().SetStoragePath( + PyToCefStringValue(path), bool(persistSessionCookies)) + +# ------------------------------------------------------------------------------ +# PyCookieVisitor +# ------------------------------------------------------------------------------ + +cdef int StoreUserCookieVisitor(object userCookieVisitor) except *: + global g_userCookieVisitorMaxId + global g_userCookieVisitors + g_userCookieVisitorMaxId += 1 + g_userCookieVisitors[g_userCookieVisitorMaxId] = userCookieVisitor + return g_userCookieVisitorMaxId + +cdef PyCookieVisitor GetPyCookieVisitor(int cookieVisitorId): + global g_userCookieVisitors + cdef object userCookieVisitor + cdef PyCookieVisitor pyCookieVisitor + if cookieVisitorId in g_userCookieVisitors: + userCookieVisitor = g_userCookieVisitors[cookieVisitorId] + pyCookieVisitor = PyCookieVisitor(userCookieVisitor) + return pyCookieVisitor + +cdef class PyCookieVisitor: + cdef object userCookieVisitor + + def __init__(self, object userCookieVisitor): + self.userCookieVisitor = userCookieVisitor + + cdef object GetCallback(self, str funcName): + if self.userCookieVisitor and ( + hasattr(self.userCookieVisitor, funcName) and ( + callable(getattr(self.userCookieVisitor, funcName)))): + return getattr(self.userCookieVisitor, funcName) + +# ------------------------------------------------------------------------------ +# C++ CookieVisitor +# ------------------------------------------------------------------------------ + +cdef public cpp_bool CookieVisitor_Visit( + int cookieVisitorId, + const CefCookie& cookie, + int count, + int total, + cpp_bool& deleteCookie + ) except * with gil: + cdef PyCookieVisitor pyCookieVisitor + cdef object callback + cdef py_bool ret + cdef PyCookie pyCookie + cdef list pyDeleteCookie = [False] + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyCookieVisitor = GetPyCookieVisitor(cookieVisitorId) + pyCookie = CreatePyCookie(cookie) + if pyCookieVisitor: + callback = pyCookieVisitor.GetCallback("Visit") + if callback: + ret = callback(pyCookie, count, total, pyDeleteCookie) + (&deleteCookie)[0] = bool(pyDeleteCookie[0]) + return bool(ret) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/cpp_utils/.gitignore b/cefpython/cpp_utils/.gitignore new file mode 100644 index 00000000..151a620f --- /dev/null +++ b/cefpython/cpp_utils/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a \ No newline at end of file diff --git a/cefpython/cpp_utils/Makefile b/cefpython/cpp_utils/Makefile new file mode 100644 index 00000000..9e589e80 --- /dev/null +++ b/cefpython/cpp_utils/Makefile @@ -0,0 +1,21 @@ +CC = g++ +CCFLAGS = -g $(CEF_CCFLAGS) + +SRC = PaintBuffer.cpp +OBJ = $(SRC:.cpp=.o) +OUT = libcpp_utils.a + +INC = -I./../ -I/usr/include/gtk-2.0 \ + -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \ + -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \ + -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \ + -I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ + -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \ + -I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \ + -I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include + +.cpp.o: + $(CC) -fPIC $(INC) $(CCFLAGS) -c $< -o $@ + +$(OUT): $(OBJ) + ar rcs $(OUT) $(OBJ) diff --git a/cefpython/cpp_utils/PaintBuffer.cpp b/cefpython/cpp_utils/PaintBuffer.cpp new file mode 100644 index 00000000..ebaa0356 --- /dev/null +++ b/cefpython/cpp_utils/PaintBuffer.cpp @@ -0,0 +1 @@ +#include "PaintBuffer.h" diff --git a/cefpython/cpp_utils/PaintBuffer.h b/cefpython/cpp_utils/PaintBuffer.h new file mode 100644 index 00000000..7a9d0642 --- /dev/null +++ b/cefpython/cpp_utils/PaintBuffer.h @@ -0,0 +1,48 @@ +// Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +// License: New BSD License. +// Website: http://code.google.com/p/cefpython/ + +#pragma once + +// OS_WIN is not defined on Windows when CEF is not included. +// _WIN32 is defined on both 32bit and 64bit. +#if defined(_WIN32) +#include "windows.h" +#include "stdint_win.h" +#include +#else +#include +#include +#endif + +void FlipBufferUpsideDown(void* _dest, const void* _src, int width, int height \ + ) { + // In CEF the buffer passed to Browser.GetImage() & RenderHandler.OnPaint() + // has upper-left origin, but some libraries like Panda3D require + // bottom-left origin. + int32_t* dest = (int32_t*)_dest; + int32_t* src = (int32_t*)_src; + unsigned int tb; + int length = width*height; + for (int y = 0; y < height; y++) { + tb = length - ((y+1)*width); + memcpy(&dest[tb], &src[y*width], width*4); + } +} + +void SwapBufferFromBgraToRgba(void* _dest, const void* _src, int width, \ + int height) { + int32_t* dest = (int32_t*)_dest; + int32_t* src = (int32_t*)_src; + int32_t rgba; + int32_t bgra; + int length = width*height; + for (int i = 0; i < length; i++) { + bgra = src[i]; + // BGRA in hex = 0xAARRGGBB. + rgba = (bgra & 0x00ff0000) >> 16 // Red >> Blue. + | (bgra & 0xff00ff00) // Green Alpha. + | (bgra & 0x000000ff) << 16; // Blue >> Red. + dest[i] = rgba; + } +} diff --git a/cefpython/cpp_utils/cpp_utils_32bit.vcproj b/cefpython/cpp_utils/cpp_utils_32bit.vcproj new file mode 100644 index 00000000..bf3ca53f --- /dev/null +++ b/cefpython/cpp_utils/cpp_utils_32bit.vcproj @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cpp_utils/cpp_utils_64bit.vcproj b/cefpython/cpp_utils/cpp_utils_64bit.vcproj new file mode 100644 index 00000000..12ff59cf --- /dev/null +++ b/cefpython/cpp_utils/cpp_utils_64bit.vcproj @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cefpython/cpp_utils/stdint_win.h b/cefpython/cpp_utils/stdint_win.h new file mode 100644 index 00000000..d02608a5 --- /dev/null +++ b/cefpython/cpp_utils/stdint_win.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/cefpython/ctags.bat b/cefpython/ctags.bat new file mode 100644 index 00000000..4ea2c523 --- /dev/null +++ b/cefpython/ctags.bat @@ -0,0 +1,10 @@ +REM CTags provides code completion, finding definition/use of an identifier, +REM it supports 41 languages including Cython, see: http://ctags.sourceforge.net/ +REM Many editors are supported, see http://ctags.sourceforge.net/tools.html , +REM though there are much more, but unlisted there. + +REM kinds: p = function prototypes [off by default] +REM --c++-kinds=+p + +call C:\ctags58\ctags.exe -R --c++-kinds=+p --exclude=setup --exclude=cefpython_py27.py --exclude=cefpython_py32.py -f ctags +pause \ No newline at end of file diff --git a/cefpython/cython_includes/cef_app.pxd b/cefpython/cython_includes/cef_app.pxd new file mode 100644 index 00000000..9b4de4df --- /dev/null +++ b/cefpython/cython_includes/cef_app.pxd @@ -0,0 +1,43 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Circular imports are allowed in form "cimport ...", +# but won't work if you do "from ... cimport *". + +include "compile_time_constants.pxi" + +from cef_types_wrappers cimport CefSettings +from cef_ptr cimport CefRefPtr +from cef_base cimport CefBase +from libcpp cimport bool as cpp_bool + +IF CEF_VERSION == 3: + IF UNAME_SYSNAME == "Windows": + from cef_win cimport CefMainArgs + ELIF UNAME_SYSNAME == "Linux": + from cef_linux cimport CefMainArgs + ELIF UNAME_SYSNAME == "Darwin": + from cef_mac cimport CefMainArgs + +cdef extern from "include/cef_app.h": + + cdef cppclass CefApp(CefBase): + pass + + IF CEF_VERSION == 3: + cdef int CefExecuteProcess(CefMainArgs& args, CefRefPtr[CefApp] application) nogil + + IF CEF_VERSION == 1: + cdef cpp_bool CefInitialize(CefSettings&, CefRefPtr[CefApp]) nogil + ELIF CEF_VERSION == 3: + cdef cpp_bool CefInitialize(CefMainArgs&, CefSettings&, CefRefPtr[CefApp]) nogil + + cdef void CefRunMessageLoop() nogil + cdef void CefDoMessageLoopWork() nogil + cdef void CefQuitMessageLoop() nogil + cdef void CefShutdown() nogil + + IF CEF_VERSION == 3: + cdef void CefSetOSModalLoop(cpp_bool osModalLoop) nogil + diff --git a/cefpython/cython_includes/cef_base.pxd b/cefpython/cython_includes/cef_base.pxd new file mode 100644 index 00000000..00646bf7 --- /dev/null +++ b/cefpython/cython_includes/cef_base.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/cef_base.h": + + cdef cppclass CefBase: + int AddRef() + int Release() + int GetRefCt() diff --git a/cefpython/cython_includes/cef_browser.pxd b/cefpython/cython_includes/cef_browser.pxd new file mode 100644 index 00000000..bcab0653 --- /dev/null +++ b/cefpython/cython_includes/cef_browser.pxd @@ -0,0 +1,165 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_ptr cimport CefRefPtr +from cef_base cimport CefBase +from cef_string cimport CefString +from cef_client cimport CefClient +from libcpp cimport bool as cpp_bool +from libcpp.vector cimport vector as cpp_vector +from cef_frame cimport CefFrame +cimport cef_types +from cef_platform cimport CefKeyInfo +from cef_types cimport int64 + +IF CEF_VERSION == 1: + from cef_types_wrappers cimport CefRect + +IF CEF_VERSION == 3: + from cef_process_message cimport CefProcessMessage, CefProcessId + +IF UNAME_SYSNAME == "Windows": + from cef_win cimport CefWindowHandle, CefWindowInfo +ELIF UNAME_SYSNAME == "Linux": + from cef_linux cimport CefWindowHandle, CefWindowInfo +ELIF UNAME_SYSNAME == "Darwin": + from cef_mac cimport CefWindowHandle, CefWindowInfo + +cdef extern from "include/cef_browser.h": + + IF CEF_VERSION == 1: + + cdef cppclass CefBrowser(CefBase): + + cpp_bool CanGoBack() + cpp_bool CanGoForward() + void ClearHistory() + void CloseBrowser() + void CloseDevTools() + void Find(int identifier, CefString& searchText, cpp_bool forward, + cpp_bool matchCase, cpp_bool findNext) + CefRefPtr[CefFrame] GetFocusedFrame() + CefRefPtr[CefFrame] GetFrame(CefString& name) + void GetFrameNames(cpp_vector[CefString]& names) + CefRefPtr[CefFrame] GetMainFrame() + CefWindowHandle GetOpenerWindowHandle() + CefWindowHandle GetWindowHandle() + double GetZoomLevel() + void GoBack() + void GoForward() + cpp_bool HasDocument() + void HidePopup() + cpp_bool IsPopup() + void ParentWindowWillClose() + void Reload() + void ReloadIgnoreCache() + void SetFocus(cpp_bool enable) + void SetZoomLevel(double zoomLevel) + void ShowDevTools() + void StopLoad() + void StopFinding(cpp_bool clearSelection) + cpp_bool IsWindowRenderingDisabled() + cpp_bool IsPopupVisible() + int GetIdentifier() + + # Off-screen rendering. + + cpp_bool GetSize(cef_types.cef_paint_element_type_t type, + int& width, int& height) + void SetSize(cef_types.cef_paint_element_type_t type, + int width, int height) + void Invalidate(CefRect& dirtyRect) + cpp_bool GetImage(cef_types.cef_paint_element_type_t type, + int width, int height, void* buffer) + + # Sending mouse/key events. + void SendKeyEvent(cef_types.cef_key_type_t type, + CefKeyInfo& keyInfo, int modifiers) + void SendMouseClickEvent(int x, int y, + cef_types.cef_mouse_button_type_t type, + cpp_bool mouseUp, int clickCount) + void SendMouseMoveEvent(int x, int y, cpp_bool mouseLeave) + void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) + void SendFocusEvent(cpp_bool setFocus) + void SendCaptureLostEvent() + + # virtual CefRefPtr GetClient() =0; + + ELIF CEF_VERSION == 3: + + cdef cppclass CefBrowserHost(CefBase): + + void CloseBrowser(cpp_bool force_close) + void ParentWindowWillClose() + CefRefPtr[CefBrowser] GetBrowser() + void SetFocus(cpp_bool enable) + CefWindowHandle GetWindowHandle() + CefWindowHandle GetOpenerWindowHandle() + double GetZoomLevel() + void SetZoomLevel(double zoomLevel) + + CefString GetDevToolsURL(cpp_bool http_scheme) + # virtual void RunFileDialog(FileDialogMode mode, + # const CefString& title, + # const CefString& default_file_name, + # const std::vector& accept_types, + # CefRefPtr callback) =0; + # typedef cef_file_dialog_mode_t FileDialogMode; + + void StartDownload(const CefString& url) + void SetMouseCursorChangeDisabled(cpp_bool disabled) + cpp_bool IsMouseCursorChangeDisabled() + cpp_bool IsWindowRenderingDisabled() + void WasResized() + void WasHidden(cpp_bool hidden) + void NotifyScreenInfoChanged() + + # Sending mouse/key events. + void SendKeyEvent(cef_types.CefKeyEvent) + void SendMouseClickEvent(cef_types.CefMouseEvent, + cef_types.cef_mouse_button_type_t type, + cpp_bool mouseUp, int clickCount) + void SendMouseMoveEvent(cef_types.CefMouseEvent, \ + cpp_bool mouseLeave) + void SendMouseWheelEvent(cef_types.CefMouseEvent, int deltaX, \ + int deltaY) + void SendFocusEvent(cpp_bool setFocus) + void SendCaptureLostEvent() + + void Find(int identifier, const CefString& searchText, cpp_bool forward, + cpp_bool matchCase, cpp_bool findNext) + void StopFinding(cpp_bool clearSelection) + void Print() + + cdef cppclass CefBrowser(CefBase): + + CefRefPtr[CefBrowserHost] GetHost() + cpp_bool CanGoBack() + cpp_bool CanGoForward() + CefRefPtr[CefFrame] GetFocusedFrame() + CefRefPtr[CefFrame] GetFrame(CefString& name) + CefRefPtr[CefFrame] GetFrame(int64 identifier) + void GetFrameNames(cpp_vector[CefString]& names) + CefRefPtr[CefFrame] GetMainFrame() + void GoBack() + void GoForward() + cpp_bool HasDocument() + cpp_bool IsPopup() + void Reload() + void ReloadIgnoreCache() + void StopLoad() + cpp_bool IsLoading() + int GetIdentifier() + + # CefRefPtr GetFrame(int64 identifier) =0; + # virtual CefRefPtr GetClient() =0; + cpp_bool SendProcessMessage(CefProcessId target_process, + CefRefPtr[CefProcessMessage] message) + + # class CefRunFileDialogCallback : public virtual CefBase { + # virtual void OnFileDialogDismissed( + # CefRefPtr browser_host, + # const std::vector& file_paths) =0; diff --git a/cefpython/cython_includes/cef_browser_static.pxd b/cefpython/cython_includes/cef_browser_static.pxd new file mode 100644 index 00000000..40d300d5 --- /dev/null +++ b/cefpython/cython_includes/cef_browser_static.pxd @@ -0,0 +1,42 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_ptr cimport CefRefPtr +IF UNAME_SYSNAME == "Windows": + from cef_win cimport CefWindowHandle, CefWindowInfo +ELIF UNAME_SYSNAME == "Linux": + from cef_linux cimport CefWindowHandle, CefWindowInfo +ELIF UNAME_SYSNAME == "Darwin": + from cef_mac cimport CefWindowHandle, CefWindowInfo +from cef_client cimport CefClient +from cef_types_wrappers cimport CefBrowserSettings +from cef_request_context cimport CefRequestContext +from cef_browser cimport CefBrowser +from libcpp cimport bool as cpp_bool +from cef_string cimport CefString + +IF CEF_VERSION == 1: + + # Specifying namespace allows to import a static method. + cdef extern from "include/cef_browser.h" namespace "CefBrowser": + + cdef CefRefPtr[CefBrowser] CreateBrowserSync( + CefWindowInfo&, + CefRefPtr[CefClient], + CefString&, + CefBrowserSettings&) nogil + +ELIF CEF_VERSION == 3: + + # Specifying namespace allows to import a static method. + cdef extern from "include/cef_browser.h" namespace "CefBrowserHost": + + cdef CefRefPtr[CefBrowser] CreateBrowserSync( + CefWindowInfo&, + CefRefPtr[CefClient], + CefString&, + CefBrowserSettings&, + CefRefPtr[CefRequestContext]) nogil diff --git a/cefpython/cython_includes/cef_callback_cef3.pxd b/cefpython/cython_includes/cef_callback_cef3.pxd new file mode 100644 index 00000000..7a52965e --- /dev/null +++ b/cefpython/cython_includes/cef_callback_cef3.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_callback.h": + cdef cppclass CefCallback(CefBase): + void Continue() + void Cancel() diff --git a/cefpython/cython_includes/cef_client.pxd b/cefpython/cython_includes/cef_client.pxd new file mode 100644 index 00000000..af73dce5 --- /dev/null +++ b/cefpython/cython_includes/cef_client.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_client.h": + + cdef cppclass CefClient(CefBase): + pass diff --git a/cefpython/cython_includes/cef_command_line.pxd b/cefpython/cython_includes/cef_command_line.pxd new file mode 100644 index 00000000..e2d9cf3d --- /dev/null +++ b/cefpython/cython_includes/cef_command_line.pxd @@ -0,0 +1,20 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Circular imports are allowed in form "cimport ...", +# but won't work if you do "from ... cimport *". + +include "compile_time_constants.pxi" + +from cef_base cimport CefBase +from cef_string cimport CefString +from libcpp cimport bool as cpp_bool + +cdef extern from "include/cef_command_line.h": + cdef cppclass CefCommandLine(CefBase): + void AppendSwitch(CefString& name) + void AppendSwitchWithValue(CefString& name, CefString& value) + CefString GetCommandLineString() + cpp_bool HasSwitch(const CefString& name) + CefString GetSwitchValue(const CefString& name) diff --git a/cefpython/cython_includes/cef_content_filter.pxd b/cefpython/cython_includes/cef_content_filter.pxd new file mode 100644 index 00000000..5c63a549 --- /dev/null +++ b/cefpython/cython_includes/cef_content_filter.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_content_filter.h": + cdef cppclass CefContentFilter(CefBase): + pass diff --git a/cefpython/cython_includes/cef_cookie_cef1.pxd b/cefpython/cython_includes/cef_cookie_cef1.pxd new file mode 100644 index 00000000..5dc31468 --- /dev/null +++ b/cefpython/cython_includes/cef_cookie_cef1.pxd @@ -0,0 +1,40 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport cef_string_t +from libcpp cimport bool as cpp_bool +from cef_time cimport cef_time_t +from libcpp.vector cimport vector as cpp_vector +from cef_string cimport CefString +from cef_ptr cimport CefRefPtr + +cdef extern from "include/cef_cookie.h": + ctypedef struct CefCookie: + cef_string_t name + cef_string_t value + cef_string_t domain + cef_string_t path + cpp_bool secure + cpp_bool httponly + cef_time_t creation + cef_time_t last_access + cpp_bool has_expires + cef_time_t expires + cdef CefRefPtr[CefCookieManager] CefCookieManager_GetGlobalManager \ + "CefCookieManager::GetGlobalManager"() + cdef CefRefPtr[CefCookieManager] CefCookieManager_CreateManager \ + "CefCookieManager::CreateManager"(const CefString& path) + cdef cppclass CefCookieManager: + void SetSupportedSchemes(const cpp_vector[CefString]& schemes) + cpp_bool VisitAllCookies(CefRefPtr[CefCookieVisitor] visitor) + cpp_bool VisitUrlCookies(const CefString& url, + cpp_bool includeHttpOnly, + CefRefPtr[CefCookieVisitor] visitor) + cpp_bool SetCookie(const CefString& url, const CefCookie& cookie) + cpp_bool DeleteCookies(const CefString& url, + const CefString& cookie_name) + cpp_bool SetStoragePath(const CefString& path) + + cdef cppclass CefCookieVisitor: + pass diff --git a/cefpython/cython_includes/cef_cookie_cef3.pxd b/cefpython/cython_includes/cef_cookie_cef3.pxd new file mode 100644 index 00000000..59c72e1f --- /dev/null +++ b/cefpython/cython_includes/cef_cookie_cef3.pxd @@ -0,0 +1,44 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport cef_string_t +from libcpp cimport bool as cpp_bool +from cef_time cimport cef_time_t +from libcpp.vector cimport vector as cpp_vector +from cef_string cimport CefString +from cef_ptr cimport CefRefPtr + +cdef extern from "include/cef_cookie.h": + ctypedef struct CefCookie: + cef_string_t name + cef_string_t value + cef_string_t domain + cef_string_t path + cpp_bool secure + cpp_bool httponly + cef_time_t creation + cef_time_t last_access + cpp_bool has_expires + cef_time_t expires + + cdef CefRefPtr[CefCookieManager] CefCookieManager_GetGlobalManager \ + "CefCookieManager::GetGlobalManager"() + cdef CefRefPtr[CefCookieManager] CefCookieManager_CreateManager \ + "CefCookieManager::CreateManager"(const CefString& path, \ + cpp_bool persist_session_cookies) + cdef cppclass CefCookieManager: + void SetSupportedSchemes(const cpp_vector[CefString]& schemes) + cpp_bool VisitAllCookies(CefRefPtr[CefCookieVisitor] visitor) + cpp_bool VisitUrlCookies(const CefString& url, + cpp_bool includeHttpOnly, + CefRefPtr[CefCookieVisitor] visitor) + cpp_bool SetCookie(const CefString& url, const CefCookie& cookie) + cpp_bool DeleteCookies(const CefString& url, + const CefString& cookie_name) + cpp_bool SetStoragePath(const CefString& path, + cpp_bool persist_session_cookies) + # cpp_bool FlushStore(CefRefPtr[CefCompletionHandler] handler) + + cdef cppclass CefCookieVisitor: + pass diff --git a/cefpython/cython_includes/cef_cookie_manager_namespace.pxd b/cefpython/cython_includes/cef_cookie_manager_namespace.pxd new file mode 100644 index 00000000..2b75ff6f --- /dev/null +++ b/cefpython/cython_includes/cef_cookie_manager_namespace.pxd @@ -0,0 +1,23 @@ +include "compile_time_constants.pxi" + +from libcpp cimport bool as cpp_bool +from cef_string cimport CefString + +IF CEF_VERSION == 1: + from cef_cookie_cef1 cimport CefCookie +ELIF CEF_VERSION == 3: + from cef_cookie_cef3 cimport CefCookie + +# We need to pass C++ class methods by reference to a function, +# it is not possible with such syntax: +# | &CefCookieManager.SetCookie +# We had to create this addional pxd file so we can pass it like this: +# | &cef_cookie_manager_namespace.SetCookie +# In cookie.pyx > PyCookieManager.SetCookie(). +# See this topic: +# https://groups.google.com/d/topic/cython-users/G-vEdIkmNNY/discussion + +cdef extern from "include/cef_cookie.h" namespace "CefCookieManager": + cpp_bool SetCookie(const CefString& url, const CefCookie& cookie) + cpp_bool DeleteCookies(const CefString& url, + const CefString& cookie_name) diff --git a/cefpython/cython_includes/cef_download_handler.pxd b/cefpython/cython_includes/cef_download_handler.pxd new file mode 100644 index 00000000..3a1915fe --- /dev/null +++ b/cefpython/cython_includes/cef_download_handler.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_download_handler.h": + + cdef cppclass CefDownloadHandler(CefBase): + pass diff --git a/cefpython/cython_includes/cef_drag.pxd b/cefpython/cython_includes/cef_drag.pxd new file mode 100644 index 00000000..35705b4c --- /dev/null +++ b/cefpython/cython_includes/cef_drag.pxd @@ -0,0 +1,16 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libc.limits cimport UINT_MAX + +cdef extern from "include/internal/cef_types.h": + cdef enum cef_drag_operations_mask_t: + DRAG_OPERATION_NONE = 0, + DRAG_OPERATION_COPY = 1, + DRAG_OPERATION_LINK = 2, + DRAG_OPERATION_GENERIC = 4, + DRAG_OPERATION_PRIVATE = 8, + DRAG_OPERATION_MOVE = 16, + DRAG_OPERATION_DELETE = 32, + DRAG_OPERATION_EVERY = UINT_MAX diff --git a/cefpython/cython_includes/cef_drag_data.pxd b/cefpython/cython_includes/cef_drag_data.pxd new file mode 100644 index 00000000..4f79942b --- /dev/null +++ b/cefpython/cython_includes/cef_drag_data.pxd @@ -0,0 +1,21 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libcpp cimport bool as cpp_bool +from cef_string cimport CefString +from libcpp.vector cimport vector as cpp_vector + +cdef extern from "include/cef_drag_data.h": + cdef cppclass CefDragData: + cpp_bool IsLink() + cpp_bool IsFragment() + cpp_bool IsFile() + CefString GetLinkURL() + CefString GetLinkTitle() + CefString GetLinkMetadata() + CefString GetFragmentText() + CefString GetFragmentHtml() + CefString GetFragmentBaseURL() + CefString GetFileName() + cpp_bool GetFileNames(cpp_vector[CefString]& names) diff --git a/cefpython/cython_includes/cef_frame.pxd b/cefpython/cython_includes/cef_frame.pxd new file mode 100644 index 00000000..0d20768c --- /dev/null +++ b/cefpython/cython_includes/cef_frame.pxd @@ -0,0 +1,70 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_base cimport CefBase +from cef_types cimport int64 +from cef_string cimport CefString +from libcpp cimport bool as cpp_bool +from cef_ptr cimport CefRefPtr +from cef_v8 cimport CefV8Context +from cef_browser cimport CefBrowser +from cef_string_visitor cimport CefStringVisitor + +cdef extern from "include/cef_frame.h": + + IF CEF_VERSION == 1: + cdef cppclass CefFrame(CefBase): + void ExecuteJavaScript(CefString& jsCode, CefString& scriptUrl, int startLine) + CefString GetURL() + int64 GetIdentifier() + CefRefPtr[CefV8Context] GetV8Context() + cpp_bool IsMain() + void LoadURL(CefString& url) + void Undo() + void Redo() + void Cut() + void Copy() + void Paste() + void Delete() + void SelectAll() + void ViewSource() + void Print() + CefString GetSource() + CefString GetText() + void LoadString(CefString& string_val, CefString& url) + # virtual void LoadStream(CefRefPtr stream, const CefString& url) =0; + cpp_bool IsFocused() + CefString GetName() + # virtual void VisitDOM(CefRefPtr visitor) =0; + CefRefPtr[CefFrame] GetParent() + CefRefPtr[CefBrowser] GetBrowser() + + ELIF CEF_VERSION == 3: + cdef cppclass CefFrame(CefBase): + cpp_bool IsValid() + void ExecuteJavaScript(CefString& jsCode, CefString& scriptUrl, int startLine) + CefString GetURL() + int64 GetIdentifier() + CefRefPtr[CefV8Context] GetV8Context() + cpp_bool IsMain() + void LoadURL(CefString& url) + void Undo() + void Redo() + void Cut() + void Copy() + void Paste() + void Delete() + void SelectAll() + void ViewSource() + # void Print() + void GetSource(CefRefPtr[CefStringVisitor] visitor) + void GetText(CefRefPtr[CefStringVisitor] visitor) + void LoadString(CefString& string_val, CefString& url) + cpp_bool IsFocused() + CefString GetName() + # virtual void VisitDOM(CefRefPtr visitor) =0; + CefRefPtr[CefFrame] GetParent() + CefRefPtr[CefBrowser] GetBrowser() diff --git a/cefpython/cython_includes/cef_jsdialog_handler.pxd b/cefpython/cython_includes/cef_jsdialog_handler.pxd new file mode 100644 index 00000000..b55f7a37 --- /dev/null +++ b/cefpython/cython_includes/cef_jsdialog_handler.pxd @@ -0,0 +1,12 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport CefString +from libcpp cimport bool as cpp_bool + +cdef extern from "include/cef_jsdialog_handler.h": + cdef cppclass CefJSDialogCallback: + void Continue(cpp_bool success, + const CefString& user_input) + diff --git a/cefpython/cython_includes/cef_linux.pxd b/cefpython/cython_includes/cef_linux.pxd new file mode 100644 index 00000000..c2f93d33 --- /dev/null +++ b/cefpython/cython_includes/cef_linux.pxd @@ -0,0 +1,26 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_types_linux cimport _cef_key_info_t +from cef_types_wrappers cimport CefStructBase +from libcpp cimport bool as cpp_bool + +cdef extern from "include/internal/cef_linux.h": + + ctypedef _cef_key_info_t CefKeyInfo + ctypedef void* CefWindowHandle + ctypedef void* CefCursorHandle + + cdef cppclass CefWindowInfo: + void SetAsChild(CefWindowHandle) + void SetTransparentPainting(cpp_bool) + void SetAsOffScreen(CefWindowHandle) + + IF CEF_VERSION == 3: + cdef cppclass CefMainArgs(CefStructBase): + CefMainArgs() + CefMainArgs(int argc_arg, char** argv_arg) + diff --git a/cefpython/cython_includes/cef_mac.pxd b/cefpython/cython_includes/cef_mac.pxd new file mode 100644 index 00000000..67343b3a --- /dev/null +++ b/cefpython/cython_includes/cef_mac.pxd @@ -0,0 +1,25 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_types_mac cimport _cef_key_info_t +from cef_types_wrappers cimport CefStructBase +from libcpp cimport bool as cpp_bool + +cdef extern from "include/internal/cef_linux.h": + ctypedef _cef_key_info_t CefKeyInfo + ctypedef void* CefWindowHandle + ctypedef void* CefCursorHandle + + cdef cppclass CefWindowInfo: + void SetAsChild(CefWindowHandle ParentView, int x, int y, int width, + int height) + void SetTransparentPainting(cpp_bool) + void SetAsOffScreen(CefWindowHandle) + + IF CEF_VERSION == 3: + cdef cppclass CefMainArgs(CefStructBase): + CefMainArgs() + CefMainArgs(int argc_arg, char** argv_arg) diff --git a/cefpython/cython_includes/cef_platform.pxd b/cefpython/cython_includes/cef_platform.pxd new file mode 100644 index 00000000..3bdced29 --- /dev/null +++ b/cefpython/cython_includes/cef_platform.pxd @@ -0,0 +1,12 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +IF UNAME_SYSNAME == "Windows": + from cef_win cimport CefWindowHandle, CefCursorHandle, CefKeyInfo, CefWindowInfo +ELIF UNAME_SYSNAME == "Darwin": + from cef_mac cimport * +ELIF UNAME_SYSNAME == "Linux": + from cef_linux cimport * diff --git a/cefpython/cython_includes/cef_process_message.pxd b/cefpython/cython_includes/cef_process_message.pxd new file mode 100644 index 00000000..b0e9fecb --- /dev/null +++ b/cefpython/cython_includes/cef_process_message.pxd @@ -0,0 +1,21 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_types cimport cef_process_id_t +from cef_ptr cimport CefRefPtr +from cef_string cimport CefString +from libcpp cimport bool as cpp_bool +from cef_values cimport CefListValue +from cef_types cimport cef_process_id_t + +cdef extern from "include/cef_process_message.h": + cdef CefRefPtr[CefProcessMessage] CefProcessMessage_Create \ + "CefProcessMessage::Create"(const CefString& name) + cdef cppclass CefProcessMessage: + cpp_bool IsValid() + cpp_bool IsReadOnly() + CefRefPtr[CefProcessMessage] Copy() + CefString GetName() + CefRefPtr[CefListValue] GetArgumentList() + ctypedef cef_process_id_t CefProcessId diff --git a/cefpython/cython_includes/cef_ptr.pxd b/cefpython/cython_includes/cef_ptr.pxd new file mode 100644 index 00000000..a3222c8d --- /dev/null +++ b/cefpython/cython_includes/cef_ptr.pxd @@ -0,0 +1,13 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/internal/cef_ptr.h": + cdef cppclass CefRefPtr[T]: + CefRefPtr() + CefRefPtr(T* p) + CefRefPtr(const CefRefPtr[T]& r) + CefRefPtr[T]& Assign "operator="(T* p) # cefBrowser.Assign(CefBrowser*) + T* get() + void swap(CefRefPtr[T]& r) + diff --git a/cefpython/cython_includes/cef_render_handler.pxd b/cefpython/cython_includes/cef_render_handler.pxd new file mode 100644 index 00000000..ca6f496b --- /dev/null +++ b/cefpython/cython_includes/cef_render_handler.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_types_wrappers cimport CefRect +from libcpp.vector cimport vector as cpp_vector + +cdef extern from "include/cef_render_handler.h": + + ctypedef cpp_vector[CefRect] CefRectVector \ No newline at end of file diff --git a/cefpython/cython_includes/cef_request_cef1.pxd b/cefpython/cython_includes/cef_request_cef1.pxd new file mode 100644 index 00000000..2eafece3 --- /dev/null +++ b/cefpython/cython_includes/cef_request_cef1.pxd @@ -0,0 +1,59 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +from cef_string cimport CefString +from cef_types cimport cef_weburlrequest_flags_t, cef_postdataelement_type_t +from libcpp.vector cimport vector as cpp_vector +from libcpp cimport bool as cpp_bool +from multimap cimport multimap as cpp_multimap + +cdef extern from "include/cef_request.h": + # This types won't be visible in pyx files! + ctypedef cpp_multimap[CefString, CefString] HeaderMap + ctypedef cef_weburlrequest_flags_t CefRequestFlags + + cdef CefRefPtr[CefRequest] CefRequest_Create "CefRequest::CreateRequest"() + cdef cppclass CefRequest(CefBase): + CefString GetURL() + void SetURL(CefString& url) + CefString GetMethod() + void SetMethod(CefString& method) + CefRefPtr[CefPostData] GetPostData() + void SetPostData(CefRefPtr[CefPostData] postData) + void GetHeaderMap(HeaderMap& headerMap) + void SetHeaderMap(HeaderMap& headerMap) + void Set(CefString& url, + CefString& method, + CefRefPtr[CefPostData] postData, + HeaderMap& headerMap) + CefRequestFlags GetFlags() + void SetFlags(CefRequestFlags flags) + CefString GetFirstPartyForCookies() + void SetFirstPartyForCookies(CefString& url) + + ctypedef cpp_vector[CefRefPtr[CefPostDataElement]] ElementVector + + cdef CefRefPtr[CefPostData] CefPostData_Create \ + "CefPostData::CreatePostData"() + cdef cppclass CefPostData(CefBase): + size_t GetElementCount() + void GetElements(ElementVector& elements) + cpp_bool RemoveElement(CefRefPtr[CefPostDataElement] element) + cpp_bool AddElement(CefRefPtr[CefPostDataElement] element) + void RemoveElements() + + ctypedef cef_postdataelement_type_t ElementType + + cdef CefRefPtr[CefPostDataElement] CefPostDataElement_Create \ + "CefPostDataElement::CreatePostDataElement"() + cdef cppclass CefPostDataElement(CefBase): + void SetToEmpty() + void SetToFile(CefString& fileName) + void SetToBytes(size_t size, void* bytes) + ElementType GetType() + CefString GetFile() + size_t GetBytesCount() + size_t GetBytes(size_t size, void* bytes) diff --git a/cefpython/cython_includes/cef_request_cef3.pxd b/cefpython/cython_includes/cef_request_cef3.pxd new file mode 100644 index 00000000..6f67a412 --- /dev/null +++ b/cefpython/cython_includes/cef_request_cef3.pxd @@ -0,0 +1,62 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +from cef_string cimport CefString +from cef_types cimport cef_urlrequest_flags_t, cef_postdataelement_type_t +from libcpp.vector cimport vector as cpp_vector +from libcpp cimport bool as cpp_bool +from multimap cimport multimap as cpp_multimap + +cdef extern from "include/cef_request.h": + # This types won't be visible in pyx files! + ctypedef cpp_multimap[CefString, CefString] HeaderMap + # ctypedef cef_urlrequest_flags_t CefRequestFlags + + cdef CefRefPtr[CefRequest] CefRequest_Create "CefRequest::Create"() + cdef cppclass CefRequest(CefBase): + cpp_bool IsReadOnly() + CefString GetURL() + void SetURL(CefString& url) + CefString GetMethod() + void SetMethod(CefString& method) + CefRefPtr[CefPostData] GetPostData() + void SetPostData(CefRefPtr[CefPostData] postData) + void GetHeaderMap(HeaderMap& headerMap) + void SetHeaderMap(HeaderMap& headerMap) + void Set(CefString& url, + CefString& method, + CefRefPtr[CefPostData] postData, + HeaderMap& headerMap) + int GetFlags() + void SetFlags(int flags) + CefString GetFirstPartyForCookies() + void SetFirstPartyForCookies(CefString& url) + + ctypedef cpp_vector[CefRefPtr[CefPostDataElement]] ElementVector + + cdef CefRefPtr[CefPostData] CefPostData_Create \ + "CefPostData::Create"() + cdef cppclass CefPostData(CefBase): + cpp_bool IsReadOnly() + size_t GetElementCount() + void GetElements(ElementVector& elements) + cpp_bool RemoveElement(CefRefPtr[CefPostDataElement] element) + cpp_bool AddElement(CefRefPtr[CefPostDataElement] element) + void RemoveElements() + + ctypedef cef_postdataelement_type_t ElementType + + cdef CefRefPtr[CefPostDataElement] CefPostDataElement_Create \ + "CefPostDataElement::Create"() + cdef cppclass CefPostDataElement(CefBase): + cpp_bool IsReadOnly() + void SetToEmpty() + void SetToFile(CefString& fileName) + void SetToBytes(size_t size, void* bytes) + ElementType GetType() + CefString GetFile() + size_t GetBytesCount() + size_t GetBytes(size_t size, void* bytes) diff --git a/cefpython/cython_includes/cef_request_context.pxd b/cefpython/cython_includes/cef_request_context.pxd new file mode 100644 index 00000000..77aaf29b --- /dev/null +++ b/cefpython/cython_includes/cef_request_context.pxd @@ -0,0 +1,14 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +from cef_request_context_handler cimport CefRequestContextHandler + +cdef extern from "include/cef_request_context.h": + cdef cppclass CefRequestContext(CefBase): + pass + cdef CefRefPtr[CefRequestContext] CefRequestContext_CreateContext\ + "CefRequestContext::CreateContext"(\ + CefRefPtr[CefRequestContextHandler] handler) diff --git a/cefpython/cython_includes/cef_request_context_handler.pxd b/cefpython/cython_includes/cef_request_context_handler.pxd new file mode 100644 index 00000000..86d51f0a --- /dev/null +++ b/cefpython/cython_includes/cef_request_context_handler.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_request_context_handler.h": + cdef cppclass CefRequestContextHandler(CefBase): + pass diff --git a/cefpython/cython_includes/cef_request_handler_cef3.pxd b/cefpython/cython_includes/cef_request_handler_cef3.pxd new file mode 100644 index 00000000..37847c9e --- /dev/null +++ b/cefpython/cython_includes/cef_request_handler_cef3.pxd @@ -0,0 +1,20 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport CefString +from libcpp cimport bool as cpp_bool + +cdef extern from "include/cef_auth_callback.h": + cdef cppclass CefAuthCallback: + void Continue(const CefString& username, + const CefString& password) + void Cancel() + +cdef extern from "include/cef_request_handler.h": + cdef cppclass CefQuotaCallback: + void Continue(cpp_bool allow) + void Cancel() + + cdef cppclass CefAllowCertificateErrorCallback: + void Continue(cpp_bool allow) diff --git a/cefpython/cython_includes/cef_resource_handler_cef3.pxd b/cefpython/cython_includes/cef_resource_handler_cef3.pxd new file mode 100644 index 00000000..42be2181 --- /dev/null +++ b/cefpython/cython_includes/cef_resource_handler_cef3.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/cef_resource_handler.h": + cdef cppclass CefResourceHandler: + pass diff --git a/cefpython/cython_includes/cef_response_cef1.pxd b/cefpython/cython_includes/cef_response_cef1.pxd new file mode 100644 index 00000000..affa85d6 --- /dev/null +++ b/cefpython/cython_includes/cef_response_cef1.pxd @@ -0,0 +1,22 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_string cimport CefString +from multimap cimport multimap as cpp_multimap + +cdef extern from "include/cef_response.h": + ctypedef cpp_multimap[CefString, CefString] CefResponseHeaderMap + + cdef cppclass CefResponse(CefBase): + int GetStatus() + void SetStatus(int status) + CefString GetStatusText() + void SetStatusText(CefString& statusText) + CefString GetMimeType() + void SetMimeType(CefString& mimeType) + CefString GetHeader(CefString& name) + void GetHeaderMap(CefResponseHeaderMap& headerMap) + void SetHeaderMap(CefResponseHeaderMap& headerMap) + diff --git a/cefpython/cython_includes/cef_response_cef3.pxd b/cefpython/cython_includes/cef_response_cef3.pxd new file mode 100644 index 00000000..f29f7396 --- /dev/null +++ b/cefpython/cython_includes/cef_response_cef3.pxd @@ -0,0 +1,26 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_string cimport CefString +from multimap cimport multimap as cpp_multimap +from libcpp cimport bool as cpp_bool +from cef_ptr cimport CefRefPtr + +cdef extern from "include/cef_response.h": + ctypedef cpp_multimap[CefString, CefString] CefResponseHeaderMap + + cdef CefRefPtr[CefResponse] CefResponse_Create "CefResponse::Create"() + + cdef cppclass CefResponse(CefBase): + cpp_bool IsReadOnly() + int GetStatus() + void SetStatus(int status) + CefString GetStatusText() + void SetStatusText(CefString& statusText) + CefString GetMimeType() + void SetMimeType(CefString& mimeType) + CefString GetHeader(CefString& name) + void GetHeaderMap(CefResponseHeaderMap& headerMap) + void SetHeaderMap(CefResponseHeaderMap& headerMap) diff --git a/cefpython/cython_includes/cef_runnable.pxd b/cefpython/cython_includes/cef_runnable.pxd new file mode 100644 index 00000000..2c4d241a --- /dev/null +++ b/cefpython/cython_includes/cef_runnable.pxd @@ -0,0 +1,39 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from cef_ptr cimport CefRefPtr +from cef_task cimport CefTask +from cef_string cimport CefString +IF CEF_VERSION == 1: + from cef_cookie_cef1 cimport CefCookie, CefCookieManager +ELIF CEF_VERSION == 3: + from cef_cookie_cef3 cimport CefCookie, CefCookieManager +from libcpp cimport bool as cpp_bool + +cdef extern from "include/cef_runnable.h": + # Cython 0.19.1 does not allow template functions, only template + # classes are supported, thus we need to wrap each type of call + # to NewCefRunnableMethod(). There is a CefRunnableMethod template + # class that could be wrapped, but it depends on MakeTuple() + # template function. + + # Wrapping NewCefRunnableMethod() for CefCookieManager.SetCookie(). + ctypedef cpp_bool (*SetCookie_type)(const CefString& url, + const CefCookie& cookie) + cdef CefRefPtr[CefTask] NewCefRunnableMethod( + CefCookieManager* obj, + SetCookie_type method, + const CefString& url, + const CefCookie& cookie) + + # Wrapping NewCefRunnableMethod() for CefCookieManager.DeleteCookies(). + ctypedef cpp_bool (*DeleteCookies_type)(const CefString& url, + const CefString& cookie_name) + cdef CefRefPtr[CefTask] NewCefRunnableMethod( + CefCookieManager* obj, + DeleteCookies_type method, + const CefString& url, + const CefString& cookie_name) diff --git a/cefpython/cython_includes/cef_stream.pxd b/cefpython/cython_includes/cef_stream.pxd new file mode 100644 index 00000000..33b26f1c --- /dev/null +++ b/cefpython/cython_includes/cef_stream.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "include/cef_stream.h": + + cdef cppclass CefStreamReader(CefBase): + pass diff --git a/cefpython/cython_includes/cef_stream_static.pxd b/cefpython/cython_includes/cef_stream_static.pxd new file mode 100644 index 00000000..0bd433fc --- /dev/null +++ b/cefpython/cython_includes/cef_stream_static.pxd @@ -0,0 +1,11 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from cef_stream cimport CefStreamReader +from cef_string cimport CefString + +cdef extern from "include/cef_stream.h" namespace "CefStreamReader": + cdef CefRefPtr[CefStreamReader] CreateForFile(const CefString& fileName) + cdef CefRefPtr[CefStreamReader] CreateForData(void* data, size_t size) \ No newline at end of file diff --git a/cefpython/cython_includes/cef_string.pxd b/cefpython/cython_includes/cef_string.pxd new file mode 100644 index 00000000..ee0f0e9a --- /dev/null +++ b/cefpython/cython_includes/cef_string.pxd @@ -0,0 +1,24 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libcpp cimport bool as cpp_bool +from libc.stddef cimport wchar_t +from libcpp.string cimport string as cpp_string +from wstring cimport wstring as cpp_wstring + +cdef extern from "include/internal/cef_string.h": + ctypedef struct cef_string_t: + pass + cdef cppclass CefString: + CefString() + CefString(cef_string_t*) + void Attach(cef_string_t* str, cpp_bool owner) + cpp_bool empty() + cpp_bool FromASCII(char*) + cpp_bool FromString(wchar_t*, size_t, cpp_bool) + cpp_bool FromString(cpp_string& str) + cpp_string ToString() + cpp_wstring ToWString() + char* c_str() + size_t length() diff --git a/cefpython/cython_includes/cef_string_visitor.pxd b/cefpython/cython_includes/cef_string_visitor.pxd new file mode 100644 index 00000000..653c43c7 --- /dev/null +++ b/cefpython/cython_includes/cef_string_visitor.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/cef_string_visitor.h": + cdef cppclass CefStringVisitor: + pass diff --git a/cefpython/cython_includes/cef_task.pxd b/cefpython/cython_includes/cef_task.pxd new file mode 100644 index 00000000..e7d10fc9 --- /dev/null +++ b/cefpython/cython_includes/cef_task.pxd @@ -0,0 +1,18 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libcpp cimport bool as cpp_bool +cimport cef_types +from cef_ptr cimport CefRefPtr + +cdef extern from "include/cef_task.h": + ctypedef int CefThreadId + ctypedef cef_types.cef_thread_id_t CefThreadId + + cdef cpp_bool CefCurrentlyOn(CefThreadId) + cdef cpp_bool CefPostTask(CefThreadId threadId, CefRefPtr[CefTask] task) + + cdef cppclass CefTask: + pass + diff --git a/cefpython/cython_includes/cef_time.pxd b/cefpython/cython_includes/cef_time.pxd new file mode 100644 index 00000000..bcc5dc75 --- /dev/null +++ b/cefpython/cython_includes/cef_time.pxd @@ -0,0 +1,23 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from ctime cimport time_t + +cdef extern from "include/internal/cef_time.h": + ctypedef struct cef_time_t: + int year + int month + int day_of_week + int day_of_month + int hour + int minute + int second + int millisecond + +cdef extern from "include/internal/cef_types_wrappers.h": + cdef cppclass CefTime: + CefTime() + CefTime(cef_time_t&) + void SetTimeT(time_t r) + time_t GetTimeT() diff --git a/cefpython/cython_includes/cef_types.pxd b/cefpython/cython_includes/cef_types.pxd new file mode 100644 index 00000000..78b8d4bf --- /dev/null +++ b/cefpython/cython_includes/cef_types.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +IF CEF_VERSION == 1: + from cef_types_cef1 cimport * +ELIF CEF_VERSION == 3: + from cef_types_cef3 cimport * diff --git a/cefpython/cython_includes/cef_types_cef1.pxd b/cefpython/cython_includes/cef_types_cef1.pxd new file mode 100644 index 00000000..afb086be --- /dev/null +++ b/cefpython/cython_includes/cef_types_cef1.pxd @@ -0,0 +1,162 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" +from libcpp cimport bool as cpp_bool +from libc.stddef cimport wchar_t + +cdef extern from "include/internal/cef_types.h": + cdef enum cef_log_severity_t: + LOGSEVERITY_VERBOSE = -1, + LOGSEVERITY_INFO, + LOGSEVERITY_WARNING, + LOGSEVERITY_ERROR, + LOGSEVERITY_ERROR_REPORT, + LOGSEVERITY_DISABLE = 99, + + cdef enum cef_thread_id_t: + TID_UI = 0, + TID_IO = 1, + TID_FILE = 2, + + ctypedef long long int64 + ctypedef unsigned int uint32 + ctypedef int int32 + + IF UNAME_SYSNAME == "Windows": + ctypedef wchar_t char16 + ELSE: + ctypedef unsigned short char16 + + # LoadHandler > OnLoadError - ErrorCode. + # Some of the constants are missing, for an up to date list see: + # http://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_error_list.h?view=markup + cdef enum cef_handler_errorcode_t: + ERR_NONE = 0, + ERR_FAILED = -2, + ERR_ABORTED = -3, + ERR_INVALID_ARGUMENT = -4, + ERR_INVALID_HANDLE = -5, + ERR_FILE_NOT_FOUND = -6, + ERR_TIMED_OUT = -7, + ERR_FILE_TOO_BIG = -8, + ERR_UNEXPECTED = -9, + ERR_ACCESS_DENIED = -10, + ERR_NOT_IMPLEMENTED = -11, + ERR_CONNECTION_CLOSED = -100, + ERR_CONNECTION_RESET = -101, + ERR_CONNECTION_REFUSED = -102, + ERR_CONNECTION_ABORTED = -103, + ERR_CONNECTION_FAILED = -104, + ERR_NAME_NOT_RESOLVED = -105, + ERR_INTERNET_DISCONNECTED = -106, + ERR_SSL_PROTOCOL_ERROR = -107, + ERR_ADDRESS_INVALID = -108, + ERR_ADDRESS_UNREACHABLE = -109, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110, + ERR_TUNNEL_CONNECTION_FAILED = -111, + ERR_NO_SSL_VERSIONS_ENABLED = -112, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113, + ERR_SSL_RENEGOTIATION_REQUESTED = -114, + ERR_CERT_COMMON_NAME_INVALID = -200, + ERR_CERT_DATE_INVALID = -201, + ERR_CERT_AUTHORITY_INVALID = -202, + ERR_CERT_CONTAINS_ERRORS = -203, + ERR_CERT_NO_REVOCATION_MECHANISM = -204, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205, + ERR_CERT_REVOKED = -206, + ERR_CERT_INVALID = -207, + ERR_CERT_END = -208, + ERR_INVALID_URL = -300, + ERR_DISALLOWED_URL_SCHEME = -301, + ERR_UNKNOWN_URL_SCHEME = -302, + ERR_TOO_MANY_REDIRECTS = -310, + ERR_UNSAFE_REDIRECT = -311, + ERR_UNSAFE_PORT = -312, + ERR_INVALID_RESPONSE = -320, + ERR_INVALID_CHUNKED_ENCODING = -321, + ERR_METHOD_NOT_SUPPORTED = -322, + ERR_UNEXPECTED_PROXY_AUTH = -323, + ERR_EMPTY_RESPONSE = -324, + ERR_RESPONSE_HEADERS_TOO_BIG = -325, + ERR_CACHE_MISS = -400, + ERR_INSECURE_RESPONSE = -501, + + # KeyboardHandler > OnKeyEvent - KeyEventType. + cdef enum cef_handler_keyevent_type_t: + KEYEVENT_RAWKEYDOWN = 0, + KEYEVENT_KEYDOWN, + KEYEVENT_KEYUP, + KEYEVENT_CHAR + cdef enum cef_handler_keyevent_modifiers_t: + KEY_SHIFT = 1 << 0, + KEY_CTRL = 1 << 1, + KEY_ALT = 1 << 2, + KEY_META = 1 << 3, + KEY_KEYPAD = 1 << 4, # Only used on Mac OS-X + + # V8 api + cdef enum cef_v8_propertyattribute_t: + V8_PROPERTY_ATTRIBUTE_NONE = 0, # Writeable, Enumerable, + # Configurable + V8_PROPERTY_ATTRIBUTE_READONLY = 1 << 0, # Not writeable + V8_PROPERTY_ATTRIBUTE_DONTENUM = 1 << 1, # Not enumerable + V8_PROPERTY_ATTRIBUTE_DONTDELETE = 1 << 2 # Not configurable + + # CefRequestHandler > OnBeforeBrowse > NavType + cdef enum cef_handler_navtype_t: + NAVTYPE_LINKCLICKED = 0, + NAVTYPE_FORMSUBMITTED, + NAVTYPE_BACKFORWARD, + NAVTYPE_RELOAD, + NAVTYPE_FORMRESUBMITTED, + NAVTYPE_OTHER, + NAVTYPE_LINKDROPPED + + # CefDisplayHandler > StatusType + cdef enum cef_handler_statustype_t: + STATUSTYPE_TEXT = 0, + STATUSTYPE_MOUSEOVER_URL, + STATUSTYPE_KEYBOARD_FOCUS_URL, + + # Browser > GetImage(), RenderHandler > OnPaint(). + ctypedef enum cef_paint_element_type_t: + PET_VIEW = 0, + PET_POPUP, + + # Browser > SendKeyEvent(). + ctypedef enum cef_key_type_t: + KT_KEYUP = 0, + KT_KEYDOWN, + KT_CHAR, + + # Browser > SendMouseClickEvent(). + ctypedef enum cef_mouse_button_type_t: + MBT_LEFT = 0, + MBT_MIDDLE, + MBT_RIGHT, + + # CefRequest + enum cef_postdataelement_type_t: + PDE_TYPE_EMPTY = 0, + PDE_TYPE_BYTES, + PDE_TYPE_FILE, + + enum cef_weburlrequest_flags_t: + WUR_FLAG_NONE = 0, + WUR_FLAG_SKIP_CACHE = 0x1, + WUR_FLAG_ALLOW_CACHED_CREDENTIALS = 0x2, + WUR_FLAG_ALLOW_COOKIES = 0x4, + WUR_FLAG_REPORT_UPLOAD_PROGRESS = 0x8, + WUR_FLAG_REPORT_LOAD_TIMING = 0x10, + WUR_FLAG_REPORT_RAW_HEADERS = 0x20 + + enum cef_weburlrequest_state_t: + WUR_STATE_UNSENT = 0, + WUR_STATE_STARTED = 1, + WUR_STATE_HEADERS_RECEIVED = 2, + WUR_STATE_LOADING = 3, + WUR_STATE_DONE = 4, + WUR_STATE_ERROR = 5, + WUR_STATE_ABORT = 6, diff --git a/cefpython/cython_includes/cef_types_cef3.pxd b/cefpython/cython_includes/cef_types_cef3.pxd new file mode 100644 index 00000000..56003fc6 --- /dev/null +++ b/cefpython/cython_includes/cef_types_cef3.pxd @@ -0,0 +1,227 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" +from libcpp cimport bool as cpp_bool +from libc.stddef cimport wchar_t + +cdef extern from "include/internal/cef_types.h": + cdef enum cef_log_severity_t: + LOGSEVERITY_DEFAULT, + LOGSEVERITY_VERBOSE, + LOGSEVERITY_INFO, + LOGSEVERITY_WARNING, + LOGSEVERITY_ERROR, + LOGSEVERITY_ERROR_REPORT, + LOGSEVERITY_DISABLE = 99, + + cdef enum cef_thread_id_t: + TID_UI, + TID_DB, + TID_FILE, + TID_FILE_USER_BLOCKING, + TID_PROCESS_LAUNCHER, + TID_CACHE, + TID_IO, + TID_RENDERER + + ctypedef unsigned int uint32 + ctypedef int int32 + ctypedef long long int64 + ctypedef unsigned long long uint64 + + IF UNAME_SYSNAME == "Windows": + ctypedef wchar_t char16 + ELSE: + ctypedef unsigned short char16 + + cdef enum cef_v8_propertyattribute_t: + V8_PROPERTY_ATTRIBUTE_NONE = 0, # Writeable, Enumerable, + # Configurable + V8_PROPERTY_ATTRIBUTE_READONLY = 1 << 0, # Not writeable + V8_PROPERTY_ATTRIBUTE_DONTENUM = 1 << 1, # Not enumerable + V8_PROPERTY_ATTRIBUTE_DONTDELETE = 1 << 2 # Not configurable + + cdef enum cef_navigation_type_t: + NAVIGATION_LINK_CLICKED = 0, + NAVIGATION_FORM_SUBMITTED, + NAVIGATION_BACK_FORWARD, + NAVIGATION_RELOAD, + NAVIGATION_FORM_RESUBMITTED, + NAVIGATION_OTHER, + + cdef enum cef_process_id_t: + PID_BROWSER, + PID_RENDERER, + + ctypedef enum cef_state_t: + STATE_DEFAULT = 0, + STATE_ENABLED, + STATE_DISABLED, + + enum cef_postdataelement_type_t: + PDE_TYPE_EMPTY = 0, + PDE_TYPE_BYTES, + PDE_TYPE_FILE, + + # WebRequest + enum cef_urlrequest_flags_t: + UR_FLAG_NONE = 0, + UR_FLAG_SKIP_CACHE = 1 << 0, + UR_FLAG_ALLOW_CACHED_CREDENTIALS = 1 << 1, + UR_FLAG_ALLOW_COOKIES = 1 << 2, + UR_FLAG_REPORT_UPLOAD_PROGRESS = 1 << 3, + UR_FLAG_REPORT_LOAD_TIMING = 1 << 4, + UR_FLAG_REPORT_RAW_HEADERS = 1 << 5, + UR_FLAG_NO_DOWNLOAD_DATA = 1 << 6, + UR_FLAG_NO_RETRY_ON_5XX = 1 << 7, + + # CefListValue, CefDictionaryValue - types. + enum cef_value_type_t: + VTYPE_INVALID = 0, + VTYPE_NULL, + VTYPE_BOOL, + VTYPE_INT, + VTYPE_DOUBLE, + VTYPE_STRING, + VTYPE_BINARY, + VTYPE_DICTIONARY, + VTYPE_LIST, + + # KeyboardHandler + ctypedef void* CefEventHandle + ctypedef enum cef_key_event_type_t: + KEYEVENT_RAWKEYDOWN = 0, + KEYEVENT_KEYDOWN, + KEYEVENT_KEYUP, + KEYEVENT_CHAR + ctypedef struct _cef_key_event_t: + cef_key_event_type_t type + uint32 modifiers + int windows_key_code + int native_key_code + int is_system_key + char16 character + char16 unmodified_character + cpp_bool focus_on_editable_field + ctypedef _cef_key_event_t CefKeyEvent + enum cef_event_flags_t: + EVENTFLAG_NONE = 0, + EVENTFLAG_CAPS_LOCK_ON = 1 << 0, + EVENTFLAG_SHIFT_DOWN = 1 << 1, + EVENTFLAG_CONTROL_DOWN = 1 << 2, + EVENTFLAG_ALT_DOWN = 1 << 3, + EVENTFLAG_LEFT_MOUSE_BUTTON = 1 << 4, + EVENTFLAG_MIDDLE_MOUSE_BUTTON = 1 << 5, + EVENTFLAG_RIGHT_MOUSE_BUTTON = 1 << 6, + # Mac OS-X command key. + EVENTFLAG_COMMAND_DOWN = 1 << 7, + EVENTFLAG_NUM_LOCK_ON = 1 << 8, + EVENTFLAG_IS_KEY_PAD = 1 << 9, + EVENTFLAG_IS_LEFT = 1 << 10, + EVENTFLAG_IS_RIGHT = 1 << 11, + + # LoadHandler + enum cef_termination_status_t: + TS_ABNORMAL_TERMINATION, + TS_PROCESS_WAS_KILLED, + TS_PROCESS_CRASHED, + enum cef_errorcode_t: + ERR_NONE = 0, + ERR_FAILED = -2, + ERR_ABORTED = -3, + ERR_INVALID_ARGUMENT = -4, + ERR_INVALID_HANDLE = -5, + ERR_FILE_NOT_FOUND = -6, + ERR_TIMED_OUT = -7, + ERR_FILE_TOO_BIG = -8, + ERR_UNEXPECTED = -9, + ERR_ACCESS_DENIED = -10, + ERR_NOT_IMPLEMENTED = -11, + ERR_CONNECTION_CLOSED = -100, + ERR_CONNECTION_RESET = -101, + ERR_CONNECTION_REFUSED = -102, + ERR_CONNECTION_ABORTED = -103, + ERR_CONNECTION_FAILED = -104, + ERR_NAME_NOT_RESOLVED = -105, + ERR_INTERNET_DISCONNECTED = -106, + ERR_SSL_PROTOCOL_ERROR = -107, + ERR_ADDRESS_INVALID = -108, + ERR_ADDRESS_UNREACHABLE = -109, + ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110, + ERR_TUNNEL_CONNECTION_FAILED = -111, + ERR_NO_SSL_VERSIONS_ENABLED = -112, + ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113, + ERR_SSL_RENEGOTIATION_REQUESTED = -114, + ERR_CERT_COMMON_NAME_INVALID = -200, + ERR_CERT_DATE_INVALID = -201, + ERR_CERT_AUTHORITY_INVALID = -202, + ERR_CERT_CONTAINS_ERRORS = -203, + ERR_CERT_NO_REVOCATION_MECHANISM = -204, + ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205, + ERR_CERT_REVOKED = -206, + ERR_CERT_INVALID = -207, + ERR_CERT_END = -208, + ERR_INVALID_URL = -300, + ERR_DISALLOWED_URL_SCHEME = -301, + ERR_UNKNOWN_URL_SCHEME = -302, + ERR_TOO_MANY_REDIRECTS = -310, + ERR_UNSAFE_REDIRECT = -311, + ERR_UNSAFE_PORT = -312, + ERR_INVALID_RESPONSE = -320, + ERR_INVALID_CHUNKED_ENCODING = -321, + ERR_METHOD_NOT_SUPPORTED = -322, + ERR_UNEXPECTED_PROXY_AUTH = -323, + ERR_EMPTY_RESPONSE = -324, + ERR_RESPONSE_HEADERS_TOO_BIG = -325, + ERR_CACHE_MISS = -400, + ERR_INSECURE_RESPONSE = -501, + + # Browser > GetImage(), RenderHandler > OnPaint(). + ctypedef enum cef_paint_element_type_t: + PET_VIEW = 0, + PET_POPUP, + + # Browser > SendMouseClickEvent(). + ctypedef enum cef_mouse_button_type_t: + MBT_LEFT = 0, + MBT_MIDDLE, + MBT_RIGHT, + ctypedef struct cef_mouse_event_t: + int x + int y + uint32 modifiers + ctypedef cef_mouse_event_t CefMouseEvent + + # RenderHandler > GetScreenInfo(): + ctypedef struct cef_rect_t: + int x + int y + int width + int height + ctypedef cef_rect_t CefRect + ctypedef struct cef_screen_info_t: + float device_scale_factor + int depth + int depth_per_component + cpp_bool is_monochrome + cef_rect_t rect + cef_rect_t available_rect + ctypedef cef_screen_info_t CefScreenInfo + + # CefURLRequest.GetStatus() + enum cef_urlrequest_status_t: + UR_UNKNOWN = 0 + UR_SUCCESS + UR_IO_PENDING + UR_CANCELED + UR_FAILED + + ctypedef uint32 cef_color_t + + # CefJSDialogHandler.OnJSDialog() + enum cef_jsdialog_type_t: + JSDIALOGTYPE_ALERT = 0, + JSDIALOGTYPE_CONFIRM, + JSDIALOGTYPE_PROMPT, diff --git a/cefpython/cython_includes/cef_types_linux.pxd b/cefpython/cython_includes/cef_types_linux.pxd new file mode 100644 index 00000000..19cd977e --- /dev/null +++ b/cefpython/cython_includes/cef_types_linux.pxd @@ -0,0 +1,8 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/internal/cef_types_linux.h": + + ctypedef struct _cef_key_info_t: + int key diff --git a/cefpython/cython_includes/cef_types_mac.pxd b/cefpython/cython_includes/cef_types_mac.pxd new file mode 100644 index 00000000..58813e16 --- /dev/null +++ b/cefpython/cython_includes/cef_types_mac.pxd @@ -0,0 +1,10 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "include/internal/cef_types_mac.h": + + ctypedef struct _cef_key_info_t: + int keyCode + int character + int characterNoModifiers diff --git a/cefpython/cython_includes/cef_types_win.pxd b/cefpython/cython_includes/cef_types_win.pxd new file mode 100644 index 00000000..14959d19 --- /dev/null +++ b/cefpython/cython_includes/cef_types_win.pxd @@ -0,0 +1,18 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from windows cimport BOOL + +cdef extern from "include/internal/cef_types_win.h": + + cdef enum cef_graphics_implementation_t: + ANGLE_IN_PROCESS = 0, + ANGLE_IN_PROCESS_COMMAND_BUFFER, + DESKTOP_IN_PROCESS, + DESKTOP_IN_PROCESS_COMMAND_BUFFER, + + ctypedef struct _cef_key_info_t: + int key + BOOL sysChar + BOOL imeChar diff --git a/cefpython/cython_includes/cef_types_wrappers.pxd b/cefpython/cython_includes/cef_types_wrappers.pxd new file mode 100644 index 00000000..8c588a75 --- /dev/null +++ b/cefpython/cython_includes/cef_types_wrappers.pxd @@ -0,0 +1,169 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from libcpp cimport bool as cpp_bool +from cef_string cimport cef_string_t +IF CEF_VERSION == 3: + from cef_types cimport cef_state_t + from cef_types cimport cef_color_t + +cdef extern from "include/internal/cef_types_wrappers.h": + + cdef cppclass CefStructBase: + pass + + IF CEF_VERSION == 1: + + ctypedef struct CefSettings: + cpp_bool multi_threaded_message_loop + cef_string_t cache_path + cef_string_t user_agent + cef_string_t product_version + cef_string_t locale + cef_string_t log_file + int log_severity + cpp_bool release_dcheck_enabled + int graphics_implementation + unsigned int local_storage_quota + unsigned int session_storage_quota + cef_string_t javascript_flags + cpp_bool auto_detect_proxy_settings_enabled + cef_string_t resources_dir_path + cef_string_t locales_dir_path + cpp_bool pack_loading_disabled + int uncaught_exception_stack_size + + ELIF CEF_VERSION == 3: + + # Sorted the same as in cef_types.h + ctypedef struct CefSettings: + cpp_bool single_process + cef_string_t browser_subprocess_path + cpp_bool multi_threaded_message_loop + cpp_bool command_line_args_disabled + cef_string_t cache_path + cpp_bool persist_session_cookies + cef_string_t user_agent + cef_string_t product_version + cef_string_t locale + cef_string_t log_file + int log_severity + cpp_bool release_dcheck_enabled + cef_string_t javascript_flags + cef_string_t resources_dir_path + cef_string_t locales_dir_path + cpp_bool pack_loading_disabled + int remote_debugging_port + int uncaught_exception_stack_size + int context_safety_implementation # Not exposed. + cpp_bool ignore_certificate_errors + cef_color_t background_color + + IF CEF_VERSION == 1: + + ctypedef struct CefBrowserSettings: + int animation_frame_rate + cpp_bool drag_drop_disabled + cpp_bool load_drops_disabled + cpp_bool history_disabled + cef_string_t standard_font_family + cef_string_t fixed_font_family + cef_string_t serif_font_family + cef_string_t sans_serif_font_family + cef_string_t cursive_font_family + cef_string_t fantasy_font_family + int default_font_size + int default_fixed_font_size + int minimum_font_size + int minimum_logical_font_size + cpp_bool remote_fonts_disabled + cef_string_t default_encoding + cpp_bool encoding_detector_enabled + cpp_bool javascript_disabled + cpp_bool javascript_open_windows_disallowed + cpp_bool javascript_close_windows_disallowed + cpp_bool javascript_access_clipboard_disallowed + cpp_bool dom_paste_disabled + cpp_bool caret_browsing_enabled + cpp_bool java_disabled + cpp_bool plugins_disabled + cpp_bool universal_access_from_file_urls_allowed + cpp_bool file_access_from_file_urls_allowed + cpp_bool web_security_disabled + cpp_bool xss_auditor_enabled + cpp_bool image_load_disabled + cpp_bool shrink_standalone_images_to_fit + cpp_bool site_specific_quirks_disabled + cpp_bool text_area_resize_disabled + cpp_bool page_cache_disabled + cpp_bool tab_to_links_disabled + cpp_bool hyperlink_auditing_disabled + cpp_bool user_style_sheet_enabled + cef_string_t user_style_sheet_location + cpp_bool author_and_user_styles_disabled + cpp_bool local_storage_disabled + cpp_bool databases_disabled + cpp_bool application_cache_disabled + cpp_bool webgl_disabled + cpp_bool accelerated_compositing_enabled + cpp_bool accelerated_layers_disabled + cpp_bool accelerated_video_disabled + cpp_bool accelerated_2d_canvas_disabled + cpp_bool accelerated_filters_disabled + cpp_bool accelerated_plugins_disabled + cpp_bool developer_tools_disabled + cpp_bool fullscreen_enabled + + ELIF CEF_VERSION == 3: + + # Sorted the same as in cef_types.h + ctypedef struct CefBrowserSettings: + cef_string_t standard_font_family + cef_string_t fixed_font_family + cef_string_t serif_font_family + cef_string_t sans_serif_font_family + cef_string_t cursive_font_family + cef_string_t fantasy_font_family + int default_font_size + int default_fixed_font_size + int minimum_font_size + int minimum_logical_font_size + cef_string_t default_encoding + cef_string_t user_style_sheet_location + cef_state_t remote_fonts + cef_state_t javascript + cef_state_t javascript_open_windows + cef_state_t javascript_close_windows + cef_state_t javascript_access_clipboard + cef_state_t javascript_dom_paste + cef_state_t caret_browsing + cef_state_t java + cef_state_t plugins + cef_state_t universal_access_from_file_urls + cef_state_t file_access_from_file_urls + cef_state_t web_security + cef_state_t image_loading + cef_state_t image_shrink_standalone_to_fit + cef_state_t text_area_resize + cef_state_t tab_to_links + cef_state_t author_and_user_styles + cef_state_t local_storage + cef_state_t databases + cef_state_t application_cache + cef_state_t webgl + cef_state_t accelerated_compositing + + IF CEF_VERSION == 1: + cdef cppclass CefRect: + int x, y, width, height + CefRect() + CefRect(int x, int y, int width, int height) + + ELIF CEF_VERSION == 3: + cdef cppclass CefRect: + int x, y, width, height + CefRect() + CefRect(int x, int y, int width, int height) diff --git a/cefpython/cython_includes/cef_urlrequest_cef3.pxd b/cefpython/cython_includes/cef_urlrequest_cef3.pxd new file mode 100644 index 00000000..1e0fae55 --- /dev/null +++ b/cefpython/cython_includes/cef_urlrequest_cef3.pxd @@ -0,0 +1,26 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +cimport cef_types +from cef_request_cef3 cimport CefRequest +from cef_response_cef3 cimport CefResponse + +cdef extern from "include/cef_urlrequest.h": + cdef CefRefPtr[CefURLRequest] CefURLRequest_Create \ + "CefURLRequest::Create"( \ + CefRefPtr[CefRequest] request, \ + CefRefPtr[CefURLRequestClient] client) + + cdef cppclass CefURLRequest(CefBase): + CefRefPtr[CefRequest] GetRequest() + CefRefPtr[CefURLRequestClient] GetClient() + cef_types.cef_urlrequest_status_t GetRequestStatus() + cef_types.cef_errorcode_t GetRequestError() + CefRefPtr[CefResponse] GetResponse() + void Cancel() + + cdef cppclass CefURLRequestClient(CefBase): + pass diff --git a/cefpython/cython_includes/cef_v8.pxd b/cefpython/cython_includes/cef_v8.pxd new file mode 100644 index 00000000..0d0bcaab --- /dev/null +++ b/cefpython/cython_includes/cef_v8.pxd @@ -0,0 +1,95 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from libcpp.vector cimport vector as cpp_vector +from cef_browser cimport CefBrowser +from cef_frame cimport CefFrame +from cef_string cimport CefString +from cef_base cimport CefBase +from libcpp cimport bool as cpp_bool +cimport cef_types + +cdef extern from "include/cef_v8.h": + + cdef cppclass CefV8Context(CefBase): + + CefRefPtr[CefV8Value] GetGlobal() + CefRefPtr[CefBrowser] GetBrowser() + CefRefPtr[CefFrame] GetFrame() + cpp_bool Enter() + cpp_bool Exit() + cpp_bool IsSame(CefRefPtr[CefV8Context] that) + + ctypedef cpp_vector[CefRefPtr[CefV8Value]] CefV8ValueList + + cdef cppclass CefV8Accessor(CefBase): + pass + + cdef cppclass CefV8Handler(CefBase): + pass + + cdef cppclass CefV8Exception(CefBase): + + int GetLineNumber() + CefString GetMessage() + CefString GetScriptResourceName() + CefString GetSourceLine() + + cdef cppclass CefV8Value(CefBase): + + CefRefPtr[CefV8Value] ExecuteFunctionWithContext( + CefRefPtr[CefV8Context] context, + CefRefPtr[CefV8Value] object, + CefV8ValueList& arguments) + + int GetArrayLength() + cpp_bool GetBoolValue() + double GetDoubleValue() + CefString GetFunctionName() + int GetIntValue() + unsigned int GetUIntValue() + cpp_bool GetKeys(cpp_vector[CefString]& keys) + CefString GetStringValue() + + CefRefPtr[CefV8Value] GetValue(CefString& key) # object's property by key + CefRefPtr[CefV8Value] GetValue(int index) # arrays index value + + cpp_bool HasValue(CefString& key) + cpp_bool HasValue(int index) + + cpp_bool SetValue(CefString& key, CefRefPtr[CefV8Value] value, cef_types.cef_v8_propertyattribute_t attribute) + cpp_bool SetValue(int index, CefRefPtr[CefV8Value] value) + + cpp_bool IsArray() + cpp_bool IsBool() + cpp_bool IsDate() + cpp_bool IsDouble() + cpp_bool IsFunction() + cpp_bool IsInt() + cpp_bool IsUInt() + cpp_bool IsNull() + cpp_bool IsObject() + cpp_bool IsString() + cpp_bool IsUndefined() + + cpp_bool HasException() + CefRefPtr[CefV8Exception] GetException() + cpp_bool ClearException() + + cdef cppclass CefV8StackTrace(CefBase): + + int GetFrameCount() + CefRefPtr[CefV8StackFrame] GetFrame(int index) + + cdef cppclass CefV8StackFrame(CefBase): + + CefString GetScriptName() + CefString GetScriptNameOrSourceURL() + CefString GetFunctionName() + int GetLineNumber() + int GetColumn() + cpp_bool IsEval() + cpp_bool IsConstructor() + diff --git a/cefpython/cython_includes/cef_v8_stack_trace.pxd b/cefpython/cython_includes/cef_v8_stack_trace.pxd new file mode 100644 index 00000000..d0fe2f41 --- /dev/null +++ b/cefpython/cython_includes/cef_v8_stack_trace.pxd @@ -0,0 +1,16 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from cef_v8 cimport CefV8StackTrace + +# Importing static methods only in this file. This is in a separate file as we do not want +# these names to be imported into global namespace, you will be using them like this: +# > cimport cef_v8_stack_trace +# > cef_v8_stack_trace.GetCurrent() + +cdef extern from "include/cef_v8.h" namespace "CefV8StackTrace": + + cdef CefRefPtr[CefV8StackTrace] GetCurrent(int frame_limit) + diff --git a/cefpython/cython_includes/cef_v8_static.pxd b/cefpython/cython_includes/cef_v8_static.pxd new file mode 100644 index 00000000..68f35e85 --- /dev/null +++ b/cefpython/cython_includes/cef_v8_static.pxd @@ -0,0 +1,35 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from cef_v8 cimport CefV8Value +from cef_string cimport CefString +from cef_v8 cimport CefV8Handler +from cef_v8 cimport CefV8Accessor +from cef_v8 cimport CefV8Context +from libcpp cimport bool as cpp_bool + +# Importing static methods only in this file. This is in a separate file as we do not want +# these names to be imported into global namespace, you will be using them like this: +# > cimport cef_v8_static +# > cef_v8_static.CreateArray() + +cdef extern from "include/cef_v8.h" namespace "CefV8Value": + + cdef CefRefPtr[CefV8Value] CreateArray(int length) + cdef CefRefPtr[CefV8Value] CreateBool(cpp_bool value) + cdef CefRefPtr[CefV8Value] CreateDouble(double value) + cdef CefRefPtr[CefV8Value] CreateFunction( + CefString& name, + CefRefPtr[CefV8Handler] handler) + cdef CefRefPtr[CefV8Value] CreateInt(int value) + cdef CefRefPtr[CefV8Value] CreateNull() + cdef CefRefPtr[CefV8Value] CreateObject(CefRefPtr[CefV8Accessor] accessor) + cdef CefRefPtr[CefV8Value] CreateString(CefString& value) + # cdef CefRefPtr[CefV8Value] CreateUndefined() + +cdef extern from "include/cef_v8.h" namespace "CefV8Context": + + cdef CefRefPtr[CefV8Context] GetCurrentContext() + diff --git a/cefpython/cython_includes/cef_values.pxd b/cefpython/cython_includes/cef_values.pxd new file mode 100644 index 00000000..f0bb4b40 --- /dev/null +++ b/cefpython/cython_includes/cef_values.pxd @@ -0,0 +1,78 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from libcpp cimport bool as cpp_bool +from cef_string cimport CefString +from libcpp.vector cimport vector +from cef_types cimport cef_value_type_t + +cdef extern from "include/cef_values.h": + cdef CefRefPtr[CefBinaryValue] CefBinaryValue_Create \ + "CefBinaryValue::Create"(const void* data, size_t data_size) + + cdef cppclass CefBinaryValue: + cpp_bool IsValid() + cpp_bool IsOwned() + CefRefPtr[CefBinaryValue] Copy() + size_t GetSize() + size_t GetData(void* buffer, size_t buffer_size, size_t data_offset) + + cdef CefRefPtr[CefDictionaryValue] CefDictionaryValue_Create \ + "CefDictionaryValue::Create"() + + cdef cppclass CefDictionaryValue: + cpp_bool IsValid() + cpp_bool IsOwned() + cpp_bool IsReadOnly() + CefRefPtr[CefDictionaryValue] Copy(cpp_bool exclude_empty_children) + size_t GetSize() + cpp_bool Clear() + cpp_bool HasKey(const CefString& key) + cpp_bool GetKeys(vector[CefString]& keys) + cpp_bool Remove(const CefString& key) + cef_value_type_t GetType(const CefString& key) + cpp_bool GetBool(const CefString& key) + int GetInt(const CefString& key) + double GetDouble(const CefString& key) + CefString GetString(const CefString& key) + CefRefPtr[CefBinaryValue] GetBinary(const CefString& key) + CefRefPtr[CefDictionaryValue] GetDictionary(const CefString& key) + CefRefPtr[CefListValue] GetList(const CefString& key) + cpp_bool SetNull(const CefString& key) + cpp_bool SetBool(const CefString& key, cpp_bool value) + cpp_bool SetInt(const CefString& key, int value) + cpp_bool SetDouble(const CefString& key, double value) + cpp_bool SetString(const CefString& key, const CefString& value) + cpp_bool SetBinary(const CefString& key, CefRefPtr[CefBinaryValue] value) + cpp_bool SetDictionary(const CefString& key, CefRefPtr[CefDictionaryValue] value) + cpp_bool SetList(const CefString& key, CefRefPtr[CefListValue] value) + + cdef CefRefPtr[CefListValue] CefListValue_Create "CefListValue::Create"() + + cdef cppclass CefListValue: + cpp_bool IsValid() + cpp_bool IsOwned() + cpp_bool IsReadOnly() + CefRefPtr[CefListValue] Copy() + cpp_bool SetSize(size_t size) + size_t GetSize() + cpp_bool Clear() + cpp_bool Remove(int index) + cef_value_type_t GetType(int index) + cpp_bool GetBool(int index) + int GetInt(int index) + double GetDouble(int index) + CefString GetString(int index) + CefRefPtr[CefBinaryValue] GetBinary(int index) + CefRefPtr[CefDictionaryValue] GetDictionary(int index) + CefRefPtr[CefListValue] GetList(int index) + cpp_bool SetNull(int index) + cpp_bool SetBool(int index, cpp_bool value) + cpp_bool SetInt(int index, int value) + cpp_bool SetDouble(int index, double value) + cpp_bool SetString(int index, const CefString& value) + cpp_bool SetBinary(int index, CefRefPtr[CefBinaryValue] value) + cpp_bool SetDictionary(int index, CefRefPtr[CefDictionaryValue] value) + cpp_bool SetList(int index, CefRefPtr[CefListValue] value) diff --git a/cefpython/cython_includes/cef_web_plugin_cef3.pxd b/cefpython/cython_includes/cef_web_plugin_cef3.pxd new file mode 100644 index 00000000..99e31d06 --- /dev/null +++ b/cefpython/cython_includes/cef_web_plugin_cef3.pxd @@ -0,0 +1,14 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport CefString + +# CEF 3 only. + +cdef extern from "include/cef_web_plugin.h": + cdef cppclass CefWebPluginInfo: + CefString GetName() + CefString GetPath() + CefString GetVersion() + CefString GetDescription() diff --git a/cefpython/cython_includes/cef_web_urlrequest_cef1.pxd b/cefpython/cython_includes/cef_web_urlrequest_cef1.pxd new file mode 100644 index 00000000..3b38e414 --- /dev/null +++ b/cefpython/cython_includes/cef_web_urlrequest_cef1.pxd @@ -0,0 +1,16 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +cimport cef_types +from cef_request_cef1 cimport CefRequest + +cdef extern from "include/cef_web_urlrequest.h": + cdef cppclass CefWebURLRequest(CefBase): + void Cancel() + cef_types.cef_weburlrequest_state_t GetState() + + cdef cppclass CefWebURLRequestClient(CefBase): + pass diff --git a/cefpython/cython_includes/cef_web_urlrequest_static_cef1.pxd b/cefpython/cython_includes/cef_web_urlrequest_static_cef1.pxd new file mode 100644 index 00000000..db981dcf --- /dev/null +++ b/cefpython/cython_includes/cef_web_urlrequest_static_cef1.pxd @@ -0,0 +1,12 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_ptr cimport CefRefPtr +from cef_web_urlrequest cimport CefWebURLRequest, CefWebURLRequestClient +from cef_request_cef1 cimport CefRequest + +cdef extern from "include/cef_web_urlrequest.h" namespace "CefWebURLRequest": + cdef CefRefPtr[CefWebURLRequest] CreateWebURLRequest( + CefRefPtr[CefRequest] request, + CefRefPtr[CefWebURLRequestClient] client) diff --git a/cefpython/cython_includes/cef_win.pxd b/cefpython/cython_includes/cef_win.pxd new file mode 100644 index 00000000..1999e937 --- /dev/null +++ b/cefpython/cython_includes/cef_win.pxd @@ -0,0 +1,28 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +include "compile_time_constants.pxi" + +from windows cimport HWND, RECT, HINSTANCE, HCURSOR +from cef_types_wrappers cimport CefStructBase +from cef_string cimport CefString +from cef_types_win cimport _cef_key_info_t + +cdef extern from "include/internal/cef_win.h": + + ctypedef HWND CefWindowHandle + ctypedef HCURSOR CefCursorHandle + + cdef cppclass CefWindowInfo: + void SetAsChild(HWND, RECT) + void SetAsPopup(HWND, CefString&) + void SetTransparentPainting(int) + void SetAsOffScreen(HWND) + + IF CEF_VERSION == 3: + cdef cppclass CefMainArgs(CefStructBase): + CefMainArgs() + CefMainArgs(HINSTANCE hInstance) + + ctypedef _cef_key_info_t CefKeyInfo diff --git a/cefpython/cython_includes/cefpython_app.pxd b/cefpython/cython_includes/cefpython_app.pxd new file mode 100644 index 00000000..09da6955 --- /dev/null +++ b/cefpython/cython_includes/cefpython_app.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_app cimport CefApp + +cdef extern from "subprocess/cefpython_app.h": + cdef cppclass CefPythonApp(CefApp): + pass diff --git a/cefpython/cython_includes/client_handler.pxd b/cefpython/cython_includes/client_handler.pxd new file mode 100644 index 00000000..48dba71d --- /dev/null +++ b/cefpython/cython_includes/client_handler.pxd @@ -0,0 +1,11 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_client cimport CefClient + +cdef extern from "client_handler/client_handler.h": + + cdef cppclass ClientHandler(CefClient): + pass + diff --git a/cefpython/cython_includes/content_filter_handler.pxd b/cefpython/cython_includes/content_filter_handler.pxd new file mode 100644 index 00000000..270d61e7 --- /dev/null +++ b/cefpython/cython_includes/content_filter_handler.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/content_filter_handler.h": + cdef cppclass ContentFilterHandler: + ContentFilterHandler(int contentFilterId) diff --git a/cefpython/cython_includes/cookie_visitor.pxd b/cefpython/cython_includes/cookie_visitor.pxd new file mode 100644 index 00000000..3c4058df --- /dev/null +++ b/cefpython/cython_includes/cookie_visitor.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/cookie_visitor.h": + cdef cppclass CookieVisitor: + CookieVisitor(int cookieVisitorId) diff --git a/cefpython/cython_includes/cpp_utils.pxd b/cefpython/cython_includes/cpp_utils.pxd new file mode 100644 index 00000000..40cb802d --- /dev/null +++ b/cefpython/cython_includes/cpp_utils.pxd @@ -0,0 +1,11 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "cpp_utils/PaintBuffer.h": + + cdef void FlipBufferUpsideDown( + void* dest, void* src, int width, int height) + + cdef void SwapBufferFromBgraToRgba( + void* dest, void* src, int width, int height) diff --git a/cefpython/cython_includes/ctime.pxd b/cefpython/cython_includes/ctime.pxd new file mode 100644 index 00000000..8771571e --- /dev/null +++ b/cefpython/cython_includes/ctime.pxd @@ -0,0 +1,22 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "time.h": + ctypedef struct time_t: + pass + ctypedef struct tm: + int tm_sec + int tm_min + int tm_hour + int tm_mday + int tm_mon + int tm_year + int tm_wday + int tm_yday + int tm_isdst + + size_t strftime (char* ptr, size_t maxsize, const char* format, + const tm* timeptr ) + tm* localtime (const time_t* timer) + time_t mktime (tm* timeptr) \ No newline at end of file diff --git a/cefpython/cython_includes/download_handler.pxd b/cefpython/cython_includes/download_handler.pxd new file mode 100644 index 00000000..450b14bd --- /dev/null +++ b/cefpython/cython_includes/download_handler.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/download_handler.h": + cdef cppclass DownloadHandler: + DownloadHandler(int downloadHandlerId) diff --git a/cefpython/cython_includes/dpi_aware_win.pxd b/cefpython/cython_includes/dpi_aware_win.pxd new file mode 100644 index 00000000..390bbf65 --- /dev/null +++ b/cefpython/cython_includes/dpi_aware_win.pxd @@ -0,0 +1,12 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libcpp cimport bool as cpp_bool + +cdef extern from "client_handler/dpi_aware.h": + cdef void GetSystemDpi(int* dpix, int* dpiy) + cdef void GetDpiAwareWindowSize(int* width, int* height) + cdef void SetProcessDpiAware() + cdef cpp_bool IsProcessDpiAware() + diff --git a/cefpython/cython_includes/http_authentication.pxd b/cefpython/cython_includes/http_authentication.pxd new file mode 100644 index 00000000..be5bfcf2 --- /dev/null +++ b/cefpython/cython_includes/http_authentication.pxd @@ -0,0 +1,16 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from windows cimport HWND +from libcpp.string cimport string as c_string + +cdef extern from "http_authentication/AuthCredentials.h": + + ctypedef struct AuthCredentialsData: + c_string username + c_string password + +cdef extern from "http_authentication/AuthDialog.h": + + cdef AuthCredentialsData* AuthDialog(HWND parent) nogil diff --git a/cefpython/cython_includes/linux.pxd b/cefpython/cython_includes/linux.pxd new file mode 100644 index 00000000..4292c8d0 --- /dev/null +++ b/cefpython/cython_includes/linux.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "gtk/gtk.h" nogil: + ctypedef void* GdkNativeWindow + ctypedef void* GtkWidget + cdef GtkWidget* gtk_plug_new(GdkNativeWindow socket_id) + cdef void gtk_widget_show(GtkWidget* widget) diff --git a/cefpython/cython_includes/mac.pxd b/cefpython/cython_includes/mac.pxd new file mode 100644 index 00000000..b9ad4cc2 --- /dev/null +++ b/cefpython/cython_includes/mac.pxd @@ -0,0 +1,6 @@ +# Copyright (c) 2015 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/util_mac.h": + cdef void MacInitialize() diff --git a/cefpython/cython_includes/multimap.pxd b/cefpython/cython_includes/multimap.pxd new file mode 100644 index 00000000..294de2a0 --- /dev/null +++ b/cefpython/cython_includes/multimap.pxd @@ -0,0 +1,22 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libcpp.utility cimport pair + +# Copied from: Cython/Includes/libcpp/map.pxd + +cdef extern from "" namespace "std": + cdef cppclass multimap[T, U]: + cppclass iterator: + pair[T, U]& operator*() nogil + iterator operator++() nogil + iterator operator--() nogil + bint operator==(iterator) nogil + bint operator!=(iterator) nogil + multimap() nogil except + + U& operator[](T&) nogil + iterator begin() nogil + iterator end() nogil + pair[iterator, bint] insert(pair[T, U]) nogil # XXX pair[T,U]& + iterator find(T&) nogil diff --git a/cefpython/cython_includes/request_context_handler.pxd b/cefpython/cython_includes/request_context_handler.pxd new file mode 100644 index 00000000..6ff9872d --- /dev/null +++ b/cefpython/cython_includes/request_context_handler.pxd @@ -0,0 +1,13 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase +from cef_ptr cimport CefRefPtr +from cef_browser cimport CefBrowser +from cef_request_context_handler cimport CefRequestContextHandler + +cdef extern from "client_handler/request_context_handler.h": + cdef cppclass RequestContextHandler(CefRequestContextHandler): + RequestContextHandler(CefRefPtr[CefBrowser] browser) + void SetBrowser(CefRefPtr[CefBrowser] browser) diff --git a/cefpython/cython_includes/resource_handler_cef3.pxd b/cefpython/cython_includes/resource_handler_cef3.pxd new file mode 100644 index 00000000..6dc0bcd7 --- /dev/null +++ b/cefpython/cython_includes/resource_handler_cef3.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/resource_handler.h": + cdef cppclass ResourceHandler: + ResourceHandler(int resourceHandlerId) diff --git a/cefpython/cython_includes/string_visitor.pxd b/cefpython/cython_includes/string_visitor.pxd new file mode 100644 index 00000000..0cd9a042 --- /dev/null +++ b/cefpython/cython_includes/string_visitor.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/string_visitor.h": + cdef cppclass StringVisitor: + StringVisitor(int stringVisitorId) diff --git a/cefpython/cython_includes/task.pxd b/cefpython/cython_includes/task.pxd new file mode 100644 index 00000000..08993f9c --- /dev/null +++ b/cefpython/cython_includes/task.pxd @@ -0,0 +1,7 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef extern from "client_handler/task.h": + void PostTaskWrapper(int threadId, int taskId) nogil + diff --git a/cefpython/cython_includes/v8function_handler.pxd b/cefpython/cython_includes/v8function_handler.pxd new file mode 100644 index 00000000..b21ead6e --- /dev/null +++ b/cefpython/cython_includes/v8function_handler.pxd @@ -0,0 +1,30 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_string cimport CefString +from cef_ptr cimport CefRefPtr +from cef_v8 cimport CefV8Value +from cef_v8 cimport CefV8ValueList +from cef_ptr cimport CefRefPtr +from cef_v8 cimport CefV8Context + +cdef extern from "v8function_handler/v8function_handler.h": + + # DelPythonCallbac() type. + ctypedef void (*RemovePythonCallback_type)( + int callbackID + ) + + cdef cppclass CefV8Handler: + pass + + # V8FunctionHandler class. + cdef cppclass V8FunctionHandler(CefV8Handler): + # V8FunctionHandler callbacks. + void SetCallback_V8Execute(V8Execute_type) + void SetCallback_RemovePythonCallback(RemovePythonCallback_type) + # Context. + void SetContext(CefRefPtr[CefV8Context]) + void SetPythonCallbackID(int callbackID) + CefRefPtr[CefV8Context] GetContext() \ No newline at end of file diff --git a/cefpython/cython_includes/web_request_client_cef1.pxd b/cefpython/cython_includes/web_request_client_cef1.pxd new file mode 100644 index 00000000..6769a664 --- /dev/null +++ b/cefpython/cython_includes/web_request_client_cef1.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "client_handler/web_request_client.h": + cdef cppclass WebRequestClient(CefBase): + WebRequestClient(int webRequestId) diff --git a/cefpython/cython_includes/web_request_client_cef3.pxd b/cefpython/cython_includes/web_request_client_cef3.pxd new file mode 100644 index 00000000..6769a664 --- /dev/null +++ b/cefpython/cython_includes/web_request_client_cef3.pxd @@ -0,0 +1,9 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from cef_base cimport CefBase + +cdef extern from "client_handler/web_request_client.h": + cdef cppclass WebRequestClient(CefBase): + WebRequestClient(int webRequestId) diff --git a/cefpython/cython_includes/windows.pxd b/cefpython/cython_includes/windows.pxd new file mode 100644 index 00000000..2e5b0763 --- /dev/null +++ b/cefpython/cython_includes/windows.pxd @@ -0,0 +1,126 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +from libc.stddef cimport wchar_t + +cdef extern from *: + ctypedef char const_char "const char" + ctypedef wchar_t const_wchar_t "const wchar_t" + +cdef extern from "stdio.h" nogil: + cdef int printf(const_char* TEMPLATE, ...) + cdef int wprintf(const_wchar_t* TEMPLATE, ...) + +cdef extern from "Windows.h" nogil: + ctypedef void* HANDLE + ctypedef HANDLE HWND + ctypedef HANDLE HINSTANCE + ctypedef HANDLE HICON + ctypedef HANDLE HDC + ctypedef HANDLE HBITMAP + ctypedef HICON HCURSOR + + ctypedef unsigned int UINT + ctypedef wchar_t* LPCTSTR + ctypedef wchar_t* LPTSTR + ctypedef int BOOL + ctypedef unsigned long DWORD + ctypedef unsigned short WORD + + cdef HINSTANCE GetModuleHandle(LPCTSTR lpModuleName) + + ctypedef struct RECT: + long left + long top + long right + long bottom + ctypedef RECT* LPRECT + + cdef UINT CP_UTF8 + cdef UINT CP_ACP + cdef DWORD WC_COMPOSITECHECK + cdef int WideCharToMultiByte(int, int, wchar_t*, int, char*, int, char*, int*) + cdef DWORD MB_COMPOSITE + cdef int MultiByteToWideChar(int, int, char*, int, wchar_t*, int) + cdef size_t mbstowcs(wchar_t *wcstr, const_char *mbstr, size_t count) + + ctypedef void* HDWP + cdef int SWP_NOZORDER + cdef HDWP BeginDeferWindowPos(int nNumWindows) + cdef HDWP DeferWindowPos( + HDWP hWinPosInfo, HWND hWnd, HWND hWndInsertAfter, + int x, int y, int cx, int cy, UINT uFlags) + cdef BOOL EndDeferWindowPos(HDWP hWinPosInfo) + + cdef BOOL GetClientRect(HWND hWnd, LPRECT lpRect) + + ctypedef unsigned int WPARAM + ctypedef unsigned int LPARAM + cdef UINT WM_SETFOCUS + cdef BOOL PostMessage( + HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) + + ctypedef unsigned int UINT_PTR + ctypedef unsigned int UINT + ctypedef struct TIMERPROC: + pass + cdef UINT_PTR SetTimer( + HWND hwnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) + cdef int USER_TIMER_MINIMUM + + # Detecting 64bit platform in an IF condition not required, see: + # https://groups.google.com/d/msg/cython-users/qb6VAR4OUms/HcLGwKwkwCgJ + ctypedef long LONG_PTR + + ctypedef LONG_PTR LRESULT + ctypedef long LONG + cdef BOOL IsZoomed(HWND hWnd) + cdef LRESULT SendMessage( + HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) + cdef UINT WM_SYSCOMMAND + cdef UINT SC_RESTORE + cdef UINT SC_MAXIMIZE + cdef int GWL_STYLE + cdef int GWL_EXSTYLE + cdef LONG GetWindowLong(HWND hWnd, int nIndex) + cdef LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong) + cdef BOOL GetWindowRect(HWND hWnd, LPRECT lpRect) + cdef int WS_CAPTION + cdef int WS_THICKFRAME + cdef int WS_EX_DLGMODALFRAME + cdef int WS_EX_WINDOWEDGE + cdef int WS_EX_CLIENTEDGE + cdef int WS_EX_STATICEDGE + cdef int MONITOR_DEFAULTTONEAREST + ctypedef HANDLE HMONITOR + ctypedef struct MONITORINFO: + DWORD cbSize + RECT rcMonitor + RECT rcWork + DWORD dwFlags + ctypedef MONITORINFO* LPMONITORINFO + cdef HMONITOR MonitorFromWindow(HWND hwnd, DWORD dwFlags) + cdef BOOL GetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi) + cdef BOOL SetWindowPos( + HWND hWnd, HWND hWndInsertAfter, + int X, int Y, int cx, int cy, UINT uFlags) + cdef int SWP_NOZORDER + cdef int SWP_NOACTIVATE + cdef int SWP_FRAMECHANGED + + cdef DWORD GetLastError() + cdef BOOL IsWindow(HWND hWnd) + + cdef LRESULT DefWindowProc( + HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) + + cdef int GetWindowTextW(HWND hWnd, wchar_t* lpString, int nMaxCount) + cdef BOOL SetWindowTextW(HWND hWnd, wchar_t* lpString) + + cdef UINT WM_GETICON + cdef UINT WM_SETICON + cdef int ICON_BIG + cdef int ICON_SMALL + cdef HWND GetParent(HWND hwnd) + diff --git a/cefpython/cython_includes/wstring.pxd b/cefpython/cython_includes/wstring.pxd new file mode 100644 index 00000000..1cee6f8a --- /dev/null +++ b/cefpython/cython_includes/wstring.pxd @@ -0,0 +1,123 @@ +from libc.stddef cimport wchar_t +from libcpp.string cimport string + +cdef extern from *: + ctypedef wchar_t const_wchar_t "const wchar_t" + +cdef extern from "" namespace "std": + + size_t npos = -1 + + cdef cppclass wstring: + wstring() nogil except + + wstring(wchar_t *) nogil except + + wstring(wchar_t *, size_t) nogil except + + wstring(string&) nogil except + + # as a string formed by a repetition of character c, n times. + wstring(size_t, char) nogil except + + + const_wchar_t* c_str() nogil + const_wchar_t* data() nogil + size_t size() nogil + size_t max_size() nogil + size_t length() nogil + void resize(size_t) nogil + void resize(size_t, char c) nogil + size_t capacity() nogil + void reserve(size_t) nogil + void clear() nogil + bint empty() nogil + + #char& at(size_t) nogil + #char& operator[](size_t) nogil + #int compare(string&) nogil + + #string& append(string&) nogil + #string& append(string&, size_t, size_t) nogil + #string& append(char *) nogil + #string& append(char *, size_t) nogil + #string& append(size_t, char) nogil + + #void push_back(char c) nogil + + #string& assign (string&) nogil + #string& assign (string&, size_t, size_t) nogil + #string& assign (char *, size_t) nogil + #string& assign (char *) nogil + #string& assign (size_t n, char c) nogil + + #string& insert(size_t, string&) nogil + #string& insert(size_t, string&, size_t, size_t) nogil + #string& insert(size_t, char* s, size_t) nogil + + + #string& insert(size_t, char* s) nogil + #string& insert(size_t, size_t, char c) nogil + + #size_t copy(char *, size_t, size_t) nogil + + #size_t find(string&) nogil + #size_t find(string&, size_t) nogil + #size_t find(char*, size_t pos, size_t) nogil + #size_t find(char*, size_t pos) nogil + #size_t find(char, size_t pos) nogil + + #size_t rfind(string&, size_t) nogil + #size_t rfind(char* s, size_t, size_t) nogil + #size_t rfind(char*, size_t pos) nogil + #size_t rfind(char c, size_t) nogil + #size_t rfind(char c) nogil + + #size_t find_first_of(string&, size_t) nogil + #size_t find_first_of(char* s, size_t, size_t) nogil + #size_t find_first_of(char*, size_t pos) nogil + #size_t find_first_of(char c, size_t) nogil + #size_t find_first_of(char c) nogil + + #size_t find_first_not_of(string&, size_t) nogil + #size_t find_first_not_of(char* s, size_t, size_t) nogil + #size_t find_first_not_of(char*, size_t pos) nogil + #size_t find_first_not_of(char c, size_t) nogil + #size_t find_first_not_of(char c) nogil + + #size_t find_last_of(string&, size_t) nogil + #size_t find_last_of(char* s, size_t, size_t) nogil + #size_t find_last_of(char*, size_t pos) nogil + #size_t find_last_of(char c, size_t) nogil + #size_t find_last_of(char c) nogil + + #size_t find_last_not_of(string&, size_t) nogil + #size_t find_last_not_of(char* s, size_t, size_t) nogil + #size_t find_last_not_of(char*, size_t pos) nogil + + #string substr(size_t, size_t) nogil + #string substr() nogil + #string substr(size_t) nogil + + #size_t find_last_not_of(char c, size_t) nogil + #size_t find_last_not_of(char c) nogil + + #string& operator= (string&) + #string& operator= (char*) + #string& operator= (char) + + #string operator+ (string& rhs) nogil + #string operator+ (char* rhs) nogil + + #bint operator==(string&) nogil + #bint operator==(char*) nogil + + #bint operator!= (string& rhs ) nogil + #bint operator!= (char* ) nogil + + #bint operator< (string&) nogil + #bint operator< (char*) nogil + + #bint operator> (string&) nogil + #bint operator> (char*) nogil + + #bint operator<= (string&) nogil + #bint operator<= (char*) nogil + + #bint operator>= (string&) nogil + #bint operator>= (char*) nogil diff --git a/cefpython/display_handler_cef1.pyx b/cefpython/display_handler_cef1.pyx new file mode 100644 index 00000000..0fd2df18 --- /dev/null +++ b/cefpython/display_handler_cef1.pyx @@ -0,0 +1,157 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +STATUSTYPE_TEXT = cef_types.STATUSTYPE_TEXT +STATUSTYPE_MOUSEOVER_URL = cef_types.STATUSTYPE_MOUSEOVER_URL +STATUSTYPE_KEYBOARD_FOCUS_URL = cef_types.STATUSTYPE_KEYBOARD_FOCUS_URL + +cdef public void DisplayHandler_OnAddressChange( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefString& cefURL + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef str pyUrl + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyUrl = CefToPyString(cefURL) + callback = pyBrowser.GetClientCallback("OnAddressChange") + if callback: + callback(pyBrowser, pyFrame, pyUrl) + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool DisplayHandler_OnConsoleMessage( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefMessage, + CefString& cefSource, + int line + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyMessage + cdef str pySource + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyMessage = CefToPyString(cefMessage) + pySource = CefToPyString(cefSource) + callback = pyBrowser.GetClientCallback("OnConsoleMessage") + if callback: + return bool(callback(pyBrowser, pyMessage, pySource, line)) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnContentsSizeChange( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + int width, + int height + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + callback = pyBrowser.GetClientCallback("OnContentsSizeChange") + if callback: + callback(pyBrowser, pyFrame, width, height) + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnNavStateChange( + CefRefPtr[CefBrowser] cefBrowser, + cpp_bool canGoBack, + cpp_bool canGoForward + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnNavStateChange") + if callback: + callback(pyBrowser, canGoBack, canGoForward) + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnStatusMessage( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefText, + cef_types.cef_handler_statustype_t statusType + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyText + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyText = CefToPyString(cefText) + callback = pyBrowser.GetClientCallback("OnStatusMessage") + if callback: + callback(pyBrowser, pyText, statusType) + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnTitleChange( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefTitle + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyTitle + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyTitle = CefToPyString(cefTitle) + callback = pyBrowser.GetClientCallback("OnTitleChange") + if callback: + ret = bool(callback(pyBrowser, pyTitle)) + IF UNAME_SYSNAME == "Windows": + if ret: + WindowUtils.SetTitle(pyBrowser, pyTitle) + WindowUtils.SetIcon(pyBrowser, icon="inherit") + return + else: + IF UNAME_SYSNAME == "Windows": + WindowUtils.SetTitle(pyBrowser, pyTitle) + WindowUtils.SetIcon(pyBrowser, icon="inherit") + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool DisplayHandler_OnTooltip( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefText + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyText + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyText = [CefToPyString(cefText)] # In/Out + callback = pyBrowser.GetClientCallback("OnTooltip") + if callback: + ret = callback(pyBrowser, pyText) + PyToCefString(pyText[0], cefText); + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/display_handler_cef3.pyx b/cefpython/display_handler_cef3.pyx new file mode 100644 index 00000000..90f3ab94 --- /dev/null +++ b/cefpython/display_handler_cef3.pyx @@ -0,0 +1,105 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void DisplayHandler_OnAddressChange( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + const CefString& cefUrl + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef py_string pyUrl + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyUrl = CefToPyString(cefUrl) + callback = pyBrowser.GetClientCallback("OnAddressChange") + if callback: + callback(pyBrowser, pyFrame, pyUrl) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnTitleChange( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefTitle + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyTitle + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyTitle = CefToPyString(cefTitle) + callback = pyBrowser.GetClientCallback("OnTitleChange") + if callback: + callback(pyBrowser, pyTitle) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool DisplayHandler_OnTooltip( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefText + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyText + cdef list pyTextOut + cdef object callback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyText = CefToPyString(cefText) + pyTextOut = [pyText] + callback = pyBrowser.GetClientCallback("OnTooltip") + if callback: + returnValue = callback(pyBrowser, pyTextOut) + # pyText and pyTextOut[0] are not the same strings! + PyToCefString(pyTextOut[0], cefText) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DisplayHandler_OnStatusMessage( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefValue + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyValue + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyValue = CefToPyString(cefValue) + callback = pyBrowser.GetClientCallback("OnStatusMessage") + if callback: + callback(pyBrowser, pyValue) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool DisplayHandler_OnConsoleMessage( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefMessage, + const CefString& cefSource, + int line + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyMessage + cdef py_string pySource + cdef py_bool returnValue + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyMessage = CefToPyString(cefMessage) + pySource = CefToPyString(cefSource) + callback = pyBrowser.GetClientCallback("OnConsoleMessage") + if callback: + returnValue = callback(pyBrowser, pyMessage, pySource, line) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/download_handler.pyx b/cefpython/download_handler.pyx new file mode 100644 index 00000000..f715d902 --- /dev/null +++ b/cefpython/download_handler.pyx @@ -0,0 +1,99 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# ------------------------------------------------------------------------------ +# Globals +# ------------------------------------------------------------------------------ + +cdef object g_userDownloadHandlers = weakref.WeakValueDictionary() +cdef int g_userDownloadHandlerMaxId = 0 + +# ------------------------------------------------------------------------------ +# PyDownloadHandler +# ------------------------------------------------------------------------------ + +cdef CefRefPtr[CefDownloadHandler] StoreUserDownloadHandler( + object userDownloadHandler) except *: + ValidateUserDownloadHandler(userDownloadHandler) + global g_userDownloadHandlerMaxId + global g_userDownloadHandlers + g_userDownloadHandlerMaxId += 1 + g_userDownloadHandlers[g_userDownloadHandlerMaxId] = userDownloadHandler + cdef CefRefPtr[CefDownloadHandler] downloadHandler = ( + new DownloadHandler( + g_userDownloadHandlerMaxId)) + return downloadHandler + +cdef object GetPyDownloadHandler(int downloadHandlerId): + global g_userDownloadHandlers + cdef object userDownloadHandler + cdef PyDownloadHandler pyDownloadHandler + if downloadHandlerId in g_userDownloadHandlers: + userDownloadHandler = g_userDownloadHandlers[downloadHandlerId] + pyDownloadHandler = PyDownloadHandler(userDownloadHandler) + return pyDownloadHandler + +cdef void ValidateUserDownloadHandler(object handler) except *: + assert handler, "DownloadHandler is empty" + has_OnData = hasattr(handler, "OnData") and ( + callable(getattr(handler, "OnData"))) + has_OnComplete = hasattr(handler, "OnComplete") and ( + callable(getattr(handler, "OnComplete"))) + assert has_OnData, "DownloadHandler is missing OnData() method" + assert has_OnComplete, "DownloadHandler is missing OnComplete() method" + +cdef class PyDownloadHandler: + cdef object userDownloadHandler + + def __init__(self, object userDownloadHandler): + assert not isinstance(userDownloadHandler, int), ( + "DownloadHandler is not a valid object") + self.userDownloadHandler = userDownloadHandler + + cdef object GetCallback(self, str funcName): + if self.userDownloadHandler and ( + hasattr(self.userDownloadHandler, funcName) and ( + callable(getattr(self.userDownloadHandler, funcName)))): + return getattr(self.userDownloadHandler, funcName) + +# ------------------------------------------------------------------------------ +# C++ DownloadHandler +# ------------------------------------------------------------------------------ + +cdef public cpp_bool DownloadHandler_ReceivedData( + int downloadHandlerId, + void* data, + int data_size + ) except * with gil: + cdef PyDownloadHandler pyDownloadHandler + cdef object callback + cdef py_bool ret + try: + assert IsThread(TID_UI), "Must be called on the UI thread" + pyDownloadHandler = GetPyDownloadHandler(downloadHandlerId) + if pyDownloadHandler: + callback = pyDownloadHandler.GetCallback("OnData") + if callback: + ret = callback(VoidPtrToString(data, data_size)) + return bool(ret) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void DownloadHandler_Complete( + int downloadHandlerId + ) except * with gil: + cdef PyDownloadHandler pyDownloadHandler + cdef object callback + try: + assert IsThread(TID_UI), "Must be called on the UI thread" + pyDownloadHandler = GetPyDownloadHandler(downloadHandlerId) + if pyDownloadHandler: + callback = pyDownloadHandler.GetCallback("OnComplete") + if callback: + callback() + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/dpi_aware_win.pyx b/cefpython/dpi_aware_win.pyx new file mode 100644 index 00000000..57abaad7 --- /dev/null +++ b/cefpython/dpi_aware_win.pyx @@ -0,0 +1,38 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class DpiAware: + + @staticmethod + def GetSystemDpi(): + # Win7 DPI (Control Panel > Appearance and Personalization > Display): + # text size Larger 150% => dpix/dpiy 144 + # text size Medium 125% => dpix/dpiy 120 + # text size Smaller 100% => dpix/dpiy 96 + # + # dpix=96 zoomlevel=0.0 + # dpix=120 zoomlevel=1.0 + # dpix=144 zoomlevel=2.0 + # dpix=72 zoomlevel=-1.0 + # + # If DPI awareness wasn't yet enabled, then GetSystemDpi + # will always return a default 96 DPI. + cdef int dpix = 0 + cdef int dpiy = 0 + GetSystemDpi(&dpix, &dpiy) + return (dpix, dpiy) + + @staticmethod + def CalculateWindowSize(int width, int height): + # Calculation for DPI < 96 is not yet supported. + GetDpiAwareWindowSize(&width, &height) + return (width, height) + + @staticmethod + def IsProcessDpiAware(): + return IsProcessDpiAware() + + @staticmethod + def SetProcessDpiAware(): + SetProcessDpiAware() diff --git a/cefpython/drag_data.pyx b/cefpython/drag_data.pyx new file mode 100644 index 00000000..10311513 --- /dev/null +++ b/cefpython/drag_data.pyx @@ -0,0 +1,57 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PyDragData CreatePyDragData(CefRefPtr[CefDragData] cefDragData): + cdef PyDragData pyDragData = PyDragData() + pyDragData.cefDragData = cefDragData + return pyDragData + +cdef class PyDragData: + cdef CefRefPtr[CefDragData] cefDragData + + cpdef py_bool IsLink(self): + return self.cefDragData.get().IsLink() + + cpdef py_bool IsFragment(self): + return self.cefDragData.get().IsFragment() + + cpdef py_bool IsFile(self): + return self.cefDragData.get().IsFile() + + cpdef str GetLinkUrl(self): + return CefToPyString(self.cefDragData.get().GetLinkURL()) + + cpdef str GetLinkTitle(self): + return CefToPyString(self.cefDragData.get().GetLinkTitle()) + + cpdef str GetLinkMetadata(self): + return CefToPyString(self.cefDragData.get().GetLinkMetadata()) + + cpdef str GetFragmentText(self): + return CefToPyString(self.cefDragData.get().GetFragmentText()) + + cpdef str GetFragmentHtml(self): + return CefToPyString(self.cefDragData.get().GetFragmentHtml()) + + cpdef str GetFragmentBaseUrl(self): + return CefToPyString(self.cefDragData.get().GetFragmentBaseURL()) + + cpdef str GetFile(self): + return CefToPyString(self.cefDragData.get().GetFileName()) + + cpdef list GetFiles(self): + cdef cpp_vector[CefString] files + cdef cpp_vector[CefString].iterator it + cdef cpp_bool succeeded = self.cefDragData.get().GetFileNames(files) + cdef CefString value + cdef list ret = [] + if succeeded: + it = files.begin() + while it != files.end(): + value = deref(it) + ret.append(CefToPyString(value)) + preinc(it) + return ret + else: + return [] diff --git a/cefpython/drag_handler.pyx b/cefpython/drag_handler.pyx new file mode 100644 index 00000000..b033a310 --- /dev/null +++ b/cefpython/drag_handler.pyx @@ -0,0 +1,61 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class Drag: + Operation = { + "None": DRAG_OPERATION_NONE, + "Copy": DRAG_OPERATION_COPY, + "Link": DRAG_OPERATION_LINK, + "Generic": DRAG_OPERATION_GENERIC, + "Private": DRAG_OPERATION_PRIVATE, + "Move" : DRAG_OPERATION_MOVE, + "Delete": DRAG_OPERATION_DELETE, + "Every": DRAG_OPERATION_EVERY, + } + +cdef public cpp_bool DragHandler_OnDragStart( + CefRefPtr[CefBrowser] browser, + CefRefPtr[CefDragData] dragData, + cef_drag_operations_mask_t mask + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyDragData pyDragData + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(browser) + pyDragData = CreatePyDragData(dragData) + callback = pyBrowser.GetClientCallback("OnDragStart") + if callback: + # The max value for mask is UINT_MAX. + ret = callback(pyBrowser, pyDragData, mask) + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool DragHandler_OnDragEnter( + CefRefPtr[CefBrowser] browser, + CefRefPtr[CefDragData] dragData, + cef_drag_operations_mask_t mask + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyDragData pyDragData + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(browser) + pyDragData = CreatePyDragData(dragData) + callback = pyBrowser.GetClientCallback("OnDragEnter") + if callback: + # The max value for mask is UINT_MAX. + ret = callback(pyBrowser, pyDragData, mask) + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/frame.pyx b/cefpython/frame.pyx new file mode 100644 index 00000000..d06c63e1 --- /dev/null +++ b/cefpython/frame.pyx @@ -0,0 +1,234 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef dict g_pyFrames = {} + +cdef object GetUniqueFrameId(int browserId, object frameId): + return str(browserId) +"#"+ str(frameId) + +cdef PyFrame GetPyFrameById(int browserId, object frameId): + cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) + if uniqueFrameId in g_pyFrames: + return g_pyFrames[uniqueFrameId] + return None + +cdef PyFrame GetPyFrame(CefRefPtr[CefFrame] cefFrame): + global g_pyFrames + if cefFrame == NULL or not cefFrame.get(): + Debug("GetPyFrame(): returning None") + return + cdef PyFrame pyFrame + # long long + cdef object frameId = cefFrame.get().GetIdentifier() + cdef int browserId = cefFrame.get().GetBrowser().get().GetIdentifier() + assert (frameId and browserId), "frameId or browserId empty" + cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) + if uniqueFrameId in g_pyFrames: + return g_pyFrames[uniqueFrameId] + for uFid, pyFrame in g_pyFrames.items(): + if not pyFrame.cefFrame.get(): + Debug("GetPyFrame(): removing an empty CefFrame reference, " \ + "uniqueFrameId = %s" % uniqueFrameId) + del g_pyFrames[uFid] + # Debug("GetPyFrame(): creating new PyFrame, frameId=%s" % frameId) + pyFrame = PyFrame(browserId, frameId) + pyFrame.cefFrame = cefFrame + g_pyFrames[uniqueFrameId] = pyFrame + return pyFrame + +cdef void RemovePyFrame(int browserId, object frameId) except *: + # Called from V8ContextHandler_OnContextReleased(). + global g_pyFrames + cdef object uniqueFrameId = GetUniqueFrameId(browserId, frameId) + if uniqueFrameId in g_pyFrames: + Debug("del g_pyFrames[%s]" % uniqueFrameId) + del g_pyFrames[uniqueFrameId] + else: + Debug("RemovePyFrame() FAILED: uniqueFrameId = %s" % uniqueFrameId) + +cdef void RemovePyFramesForBrowser(int browserId) except *: + # Called from LifespanHandler_BeforeClose(). + cdef list toRemove = [] + cdef object uniqueFrameId + cdef PyFrame pyFrame + global g_pyFrames + for uniqueFrameId, pyFrame in g_pyFrames.iteritems(): + if pyFrame.GetBrowserIdentifier() == browserId: + toRemove.append(uniqueFrameId) + for uniqueFrameId in toRemove: + Debug("del g_pyFrames[%s]" % uniqueFrameId) + del g_pyFrames[uniqueFrameId] + +cdef class PyFrame: + cdef CefRefPtr[CefFrame] cefFrame + cdef int browserId + cdef object frameId + + cdef CefRefPtr[CefFrame] GetCefFrame(self) except *: + # Do not call IsValid() here, if the frame does not exist + # then no big deal, no reason to crash the application. + # The CEF calls will fail, but they also won't cause crash. + if self.cefFrame != NULL and self.cefFrame.get(): + return self.cefFrame + raise Exception("PyFrame.GetCefFrame() failed: CefFrame was destroyed") + + def __init__(self, int browserId, int frameId): + self.browserId = browserId + self.frameId = frameId + + IF CEF_VERSION == 3: + cpdef py_bool IsValid(self): + if self.cefFrame != NULL and self.cefFrame.get() \ + and self.cefFrame.get().IsValid(): + return True + return False + + def CallFunction(self, *args): + # DEPRECATED - keep for backwards compatibility. + self.ExecuteFunction(*args) + + cpdef py_void Copy(self): + self.GetCefFrame().get().Copy() + + cpdef py_void Cut(self): + self.GetCefFrame().get().Cut() + + cpdef py_void Delete(self): + self.GetCefFrame().get().Delete() + + def ExecuteFunction(self, *args): + # No need to enter V8 context as we're calling javascript + # asynchronously using ExecuteJavascript() function. + funcName = args[0] + code = funcName+"(" + for i in range(1, len(args)): + if i != 1: + code += ", " + code += json.dumps(args[i]) + code += ")" + self.ExecuteJavascript(code) + + cpdef py_void ExecuteJavascript(self, py_string jsCode, + py_string scriptUrl="", int startLine=0): + self.GetCefFrame().get().ExecuteJavaScript(PyToCefStringValue(jsCode), + PyToCefStringValue(scriptUrl), startLine) + + cpdef object GetIdentifier(self): + # It is better to save browser and frame identifiers during + # browser instantiation. When freeing PyBrowser and PyFrame + # we need these identifiers. CefFrame and CefBrowser may already + # be freed and calling methods on these objects may fail, this + # may or may not include GetIdentifier() method, but let's be sure. + return self.frameId + + cpdef int GetBrowserIdentifier(self) except *: + return self.browserId + + cpdef str GetName(self): + return CefToPyString(self.GetCefFrame().get().GetName()) + + IF CEF_VERSION == 1: + cpdef object GetProperty(self, py_string name): + assert IsThread(TID_UI), ( + "Frame.GetProperty() may only be called on the UI thread") + cdef CefRefPtr[CefV8Context] v8Context = self.GetCefFrame().get().GetV8Context() + cdef CefRefPtr[CefV8Value] window = v8Context.get().GetGlobal() + cdef CefString cefPropertyName + PyToCefString(name, cefPropertyName) + cdef CefRefPtr[CefV8Value] v8Value = window.get().GetValue(cefPropertyName) + return V8ToPyValue(v8Value, v8Context) + + cpdef str GetSource(self): + assert IsThread(TID_UI), ( + "Frame.GetSource() may only be called on the UI thread") + return CefToPyString(self.GetCefFrame().get().GetSource()) + + cpdef str GetText(self): + assert IsThread(TID_UI), ( + "Frame.GetText() may only be called on the UI thread") + return CefToPyString(self.GetCefFrame().get().GetText()) + + IF CEF_VERSION == 3: + cpdef py_void GetSource(self, object userStringVisitor): + self.GetCefFrame().get().GetSource(CreateStringVisitor(userStringVisitor)) + + cpdef py_void GetText(self, object userStringVisitor): + self.GetCefFrame().get().GetText(CreateStringVisitor(userStringVisitor)) + + cpdef str GetUrl(self): + return CefToPyString(self.GetCefFrame().get().GetURL()) + + cpdef py_bool IsFocused(self): + IF CEF_VERSION == 1: + assert IsThread(TID_UI), ( + "Frame.IsFocused() may only be called on the UI thread") + return self.GetCefFrame().get().IsFocused() + + cpdef py_bool IsMain(self): + return self.GetCefFrame().get().IsMain() + + cpdef py_void LoadRequest(self): + pass + + cpdef py_void LoadString(self, py_string value, py_string url): + cdef CefString cefValue + cdef CefString cefUrl + PyToCefString(value, cefValue) + PyToCefString(url, cefUrl) + self.GetCefFrame().get().LoadString(cefValue, cefUrl) + + cpdef py_void LoadUrl(self, py_string url): + url = GetNavigateUrl(url) + cdef CefString cefUrl + PyToCefString(url, cefUrl) + self.GetCefFrame().get().LoadURL(cefUrl) + + cpdef py_void Paste(self): + self.GetCefFrame().get().Paste() + + IF CEF_VERSION == 1: + cpdef py_void Print(self): + self.GetCefFrame().get().Print() + + cpdef py_void Redo(self): + self.GetCefFrame().get().Redo() + + cpdef py_void SelectAll(self): + self.GetCefFrame().get().SelectAll() + + IF CEF_VERSION == 1: + cpdef py_void SetProperty(self, py_string name, object value): + assert IsThread(TID_UI), ( + "Frame.SetProperty() may only be called on the UI thread") + if not JavascriptBindings.IsValueAllowed(value): + valueType = JavascriptBindings.__IsValueAllowed(value) + raise Exception("Frame.SetProperty() failed: name=%s, " + "not allowed type: %s (this may be a type of a nested value)" + % (name, valueType)) + cdef CefRefPtr[CefV8Context] v8Context = self.GetCefFrame().get().GetV8Context() + cdef CefRefPtr[CefV8Value] window = v8Context.get().GetGlobal() + cdef CefString cefPropertyName + PyToCefString(name, cefPropertyName) + cdef cpp_bool sameContext = v8Context.get().IsSame(cef_v8_static.GetCurrentContext()) + if not sameContext: + Debug("Frame.SetProperty(): inside a different context, calling v8Context.Enter()") + assert v8Context.get().Enter(), "v8Context.Enter() failed" + window.get().SetValue( + cefPropertyName, + PyToV8Value(value, v8Context), + V8_PROPERTY_ATTRIBUTE_NONE) + if not sameContext: + assert v8Context.get().Exit(), "v8Context.Exit() failed" + + cpdef py_void Undo(self): + self.GetCefFrame().get().Undo() + + cpdef py_void ViewSource(self): + self.GetCefFrame().get().ViewSource() + + cpdef PyFrame GetParent(self): + return GetPyFrame(self.GetCefFrame().get().GetParent()) + + cpdef PyBrowser GetBrowser(self): + return GetPyBrowser(self.GetCefFrame().get().GetBrowser()) diff --git a/cefpython/http_authentication_win.pyx b/cefpython/http_authentication_win.pyx new file mode 100644 index 00000000..8cfbfcc9 --- /dev/null +++ b/cefpython/http_authentication_win.pyx @@ -0,0 +1,18 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef cpp_bool HttpAuthenticationDialog( + browser, isProxy, host, port, realm, scheme, username, password + ) except *: + cdef AuthCredentialsData* credentialsData + cdef int innerWindowHandle = browser.GetWindowHandle() + cdef HWND hwnd = innerWindowHandle + with nogil: + credentialsData = AuthDialog(hwnd) + if credentialsData == NULL: + return False + else: + username[0] = CharToPyString(credentialsData.username.c_str()) + password[0] = CharToPyString(credentialsData.password.c_str()) + return True diff --git a/cefpython/imports.pyx b/cefpython/imports.pyx new file mode 100644 index 00000000..9bc2cc1b --- /dev/null +++ b/cefpython/imports.pyx @@ -0,0 +1,181 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +import os +import sys +import cython +import platform +import traceback +import time +import types +import re +import copy +import inspect # used by JavascriptBindings.__SetObjectMethods() +import urllib +import json +import datetime +import random + +if sys.version_info.major == 2: + import urlparse +else: + from urllib import parse as urlparse + +if sys.version_info.major == 2: + from urllib import pathname2url as urllib_pathname2url +else: + from urllib.request import pathname2url as urllib_pathname2url + +from cpython.version cimport PY_MAJOR_VERSION +import weakref + +# We should allow multiple string types: str, unicode, bytes. +# PyToCefString() can handle them all. +# Important: +# If you set it to basestring, Cython will accept exactly(!) +# str/unicode in Py2 and str in Py3. This won't work in Py3 +# as we might want to pass bytes as well. Also it will +# reject string subtypes, so using it in publi API functions +# would be a bad idea. +ctypedef object py_string + +# You can't use "void" along with cpdef function returning None, it is planned to be +# added to Cython in the future, creating this virtual type temporarily. If you +# change it later to "void" then don't forget to add "except *". +ctypedef object py_void +ctypedef long WindowHandle + +from cpython cimport PyLong_FromVoidPtr + +from cpython cimport bool as py_bool +from libcpp cimport bool as cpp_bool + +from libcpp.map cimport map as cpp_map +from multimap cimport multimap as cpp_multimap +from libcpp.pair cimport pair as cpp_pair +from libcpp.vector cimport vector as cpp_vector + +from libcpp.string cimport string as cpp_string +from wstring cimport wstring as cpp_wstring + +from libc.string cimport strlen +from libc.string cimport memcpy + +# preincrement and dereference must be "as" otherwise not seen. +from cython.operator cimport preincrement as preinc, dereference as deref + +# from cython.operator cimport address as addr # Address of an c++ object? + +from libc.stdlib cimport calloc, malloc, free +from libc.stdlib cimport atoi + +# When pyx file cimports * from a pxd file and that pxd cimports * from another pxd +# then these names will be visible in pyx file. + +# Circular imports are allowed in form "cimport ...", but won't work if you do +# "from ... cimport *", this is important to know in pxd files. + +from libc.stdint cimport uint64_t +from libc.stdint cimport uintptr_t + +cimport ctime + +IF UNAME_SYSNAME == "Windows": + from windows cimport * + from dpi_aware_win cimport * +ELIF UNAME_SYSNAME == "Linux": + from linux cimport * +ELIF UNAME_SYSNAME == "Darwin": + from mac cimport * + +from cpp_utils cimport * +from task cimport * + +from cef_string cimport * +cdef extern from *: + ctypedef CefString ConstCefString "const CefString" + +from cef_types_wrappers cimport * +from cef_task cimport * +from cef_runnable cimport * + +from cef_platform cimport * + +from cef_ptr cimport * +from cef_app cimport * +from cef_browser cimport * +cimport cef_browser_static +from cef_client cimport * +from client_handler cimport * +from cef_frame cimport * + +# cannot cimport *, that would cause name conflicts with constants. +cimport cef_types +ctypedef cef_types.cef_paint_element_type_t PaintElementType +ctypedef cef_types.cef_jsdialog_type_t JSDialogType +from cef_types cimport CefKeyEvent +from cef_types cimport CefMouseEvent +from cef_types cimport CefScreenInfo + +# cannot cimport *, name conflicts +IF UNAME_SYSNAME == "Windows": + cimport cef_types_win +ELIF UNAME_SYSNAME == "Darwin": + cimport cef_types_mac +ELIF UNAME_SYSNAME == "Linux": + cimport cef_types_linux + +from cef_time cimport * +from cef_drag cimport * + +IF CEF_VERSION == 1: + from cef_v8 cimport * + cimport cef_v8_static + cimport cef_v8_stack_trace + from v8function_handler cimport * + from cef_request_cef1 cimport * + from cef_web_urlrequest_cef1 cimport * + cimport cef_web_urlrequest_static_cef1 + from web_request_client_cef1 cimport * + from cef_stream cimport * + cimport cef_stream_static + from cef_response_cef1 cimport * + from cef_stream cimport * + from cef_content_filter cimport * + from content_filter_handler cimport * + from cef_download_handler cimport * + from download_handler cimport * + from cef_cookie_cef1 cimport * + cimport cef_cookie_manager_namespace + from cookie_visitor cimport * + from cef_render_handler cimport * + from cef_drag_data cimport * + +IF UNAME_SYSNAME == "Windows": + IF CEF_VERSION == 1: + from http_authentication cimport * + +IF CEF_VERSION == 3: + from cef_values cimport * + from cefpython_app cimport * + from cef_process_message cimport * + from cef_web_plugin_cef3 cimport * + from cef_request_handler_cef3 cimport * + from cef_request_cef3 cimport * + from cef_cookie_cef3 cimport * + from cef_string_visitor cimport * + cimport cef_cookie_manager_namespace + from cookie_visitor cimport * + from string_visitor cimport * + from cef_callback_cef3 cimport * + from cef_response_cef3 cimport * + from cef_resource_handler_cef3 cimport * + from resource_handler_cef3 cimport * + from cef_urlrequest_cef3 cimport * + from web_request_client_cef3 cimport * + from cef_command_line cimport * + from cef_request_context cimport * + from cef_request_context_handler cimport * + from request_context_handler cimport * + from cef_jsdialog_handler cimport * diff --git a/cefpython/javascript_bindings.pyx b/cefpython/javascript_bindings.pyx new file mode 100644 index 00000000..ea81d8ba --- /dev/null +++ b/cefpython/javascript_bindings.pyx @@ -0,0 +1,205 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef class JavascriptBindings: + # By default binding only to top frame. + cdef public py_bool bindToFrames + cdef public py_bool bindToPopups + cdef public dict functions + cdef public dict properties + cdef public dict objects + + def __init__(self, bindToFrames=False, bindToPopups=False): + self.functions = {} + self.properties = {} + self.objects = {} + + self.bindToFrames = bool(bindToFrames) + self.bindToPopups = bool(bindToPopups) + + cpdef py_bool GetBindToFrames(self): + return bool(self.bindToFrames) + + cpdef py_bool GetBindToPopups(self): + return bool(self.bindToPopups) + + cpdef py_void SetFunction(self, py_string name, object func): + self.SetProperty(name, func) + + cpdef py_void SetObject(self, py_string name, object obj): + if not hasattr(obj, "__class__"): + raise Exception("JavascriptBindings.SetObject() failed: name=%s, " + "__class__ attribute missing, this is not an object" % name) + cdef dict methods = {} + cdef py_string key + cdef object method + cdef object predicate = inspect.ismethod + if isinstance(obj, (PyBrowser, PyFrame)): + predicate = inspect.isbuiltin + for value in inspect.getmembers(obj, predicate=predicate): + key = value[0] + method = value[1] + methods[key] = method + self.objects[name] = methods + + cpdef object GetFunction(self, py_string name): + if name in self.functions: + return self.functions[name] + + cpdef dict GetFunctions(self): + return self.functions + + cpdef dict GetObjects(self): + return self.objects + + cpdef object GetObjectMethod(self, py_string objectName, py_string methodName): + if objectName in self.objects: + if methodName in self.objects[objectName]: + return self.objects[objectName][methodName] + + cpdef object GetFunctionOrMethod(self, py_string name): + # Name can be "someFunc" or "object.someMethod". + cdef list words + if "." in name: + words = name.split(".") + return self.GetObjectMethod(words[0], words[1]) + else: + return self.GetFunction(name) + + cpdef py_void SetProperty(self, py_string name, object value): + cdef object allowed = self.IsValueAllowedRecursively(value) # returns True or string. + if allowed is not True: + raise Exception("JavascriptBindings.SetProperty() failed: name=%s, " + "not allowed type: %s (this may be a type of a nested value)" + % (name, allowed)) + + cdef object valueType = type(value) + if IsFunctionOrMethod(valueType): + self.functions[name] = value + else: + self.properties[name] = value + + + IF CEF_VERSION == 1: + cpdef py_void Rebind(self): + # Rebind may also be used for first-time bindings, in + # a case when v8 process/thread was created too fast, + # see Browser.SetJavascriptBindings() that checks whether + # OnContextCreated() event already happened, if so it will + # call Rebind() to do the javascript bindings. + assert IsThread(TID_UI), ( + "JavascriptBindings.Rebind() may only be called on UI thread") + cdef CefRefPtr[CefBrowser] cefBrowser + cdef CefRefPtr[CefFrame] cefFrame + cdef CefRefPtr[CefV8Context] v8Context + cdef cpp_bool sameContext + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef list frames + global g_pyBrowsers + for pyBrowser in g_pyBrowsers: + # These javascript bindings may have been binded + # to many browsers. + if pyBrowser.GetJavascriptBindings() != self: + continue + if self.bindToFrames: + frames = pyBrowser.GetFrames() + else: + frames = [pyBrowser.GetMainFrame()] + for frameId in self.frames: + pyBrowser = self.frames[frameId][0] + pyFrame = self.frames[frameId][1] + cefBrowser = pyBrowser.GetCefBrowser() + cefFrame = pyFrame.GetCefFrame() + v8Context = cefFrame.get().GetV8Context() + sameContext = v8Context.get().IsSame(cef_v8_static.GetCurrentContext()) + if not sameContext: + Debug("JavascriptBindings.Rebind(): inside a different context, calling v8Context.Enter()") + assert v8Context.get().Enter(), "v8Context.Enter() failed" + V8ContextHandler_OnContextCreated(cefBrowser, cefFrame, v8Context) + if not sameContext: + assert v8Context.get().Exit(), "v8Context.Exit() failed" + ELIF CEF_VERSION == 3: + cpdef py_void Rebind(self): + # In CEF Python 3 due to its multi-process architecture + # Rebind() is used for both first-time binding and rebinding. + cdef PyBrowser pyBrowser + cdef dict functions + cdef dict properties + cdef dict objects + cdef dict methods + global g_pyBrowsers + for browserId, pyBrowser in g_pyBrowsers.iteritems(): + if pyBrowser.GetJavascriptBindings() != self: + continue + # Send to the Renderer process: functions, properties, + # objects and its methods, bindToFrames. + functions = {} + for funcName in self.functions: + functions[funcName] = None + properties = self.properties + objects = {} + for objectName in self.objects: + methods = {} + for methodName in self.objects[objectName]: + methods[methodName] = None + objects[objectName] = methods + pyBrowser.SendProcessMessage(cef_types.PID_RENDERER, + 0, "DoJavascriptBindings", [{ + "functions": functions, + "properties": properties, + "objects": objects, + "bindToFrames": self.bindToFrames + }]) + + cpdef dict GetProperties(self): + return self.properties + + @staticmethod + def IsValueAllowed(object value): + return JavascriptBindings.IsValueAllowedRecursively(value) is True + + @staticmethod + def IsValueAllowedRecursively(object value, py_bool recursion=False): + # When making changes here modify also Frame.SetProperty() as it + # checks for FunctionType, MethodType. + + cdef object valueType = type(value) + cdef object valueType2 + cdef object key + + if valueType == list: + for val in value: + valueType2 = JavascriptBindings.IsValueAllowedRecursively(val, True) + if valueType2 is not True: + return valueType2.__name__ + return True + elif valueType == bool: + return True + elif valueType == float: + return True + elif valueType == int: + return True + elif valueType == type(None): + return True + elif IsFunctionOrMethod(valueType): + if recursion: + return valueType.__name__ + else: + return True + elif valueType == dict: + for key in value: + valueType2 = JavascriptBindings.IsValueAllowedRecursively(value[key], True) + if valueType2 is not True: + return valueType2.__name__ + return True + elif valueType == str or valueType == bytes: + return True + elif PY_MAJOR_VERSION < 3 and valueType == unicode: + # The unicode type is not defined in Python 3. + return True + elif valueType == tuple: + return True + else: + return valueType.__name__ diff --git a/cefpython/javascript_callback_cef1.pyx b/cefpython/javascript_callback_cef1.pyx new file mode 100644 index 00000000..95e2a719 --- /dev/null +++ b/cefpython/javascript_callback_cef1.pyx @@ -0,0 +1,123 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef cpp_map[int, CefRefPtr[CefV8Value]] g_v8JavascriptCallbacks +cdef cpp_map[int, CefRefPtr[CefV8Context]] g_v8JavascriptCallbackContexts +# Next callbackId. +cdef int g_v8JavascriptCallbackCount = 0 + +cdef int PutV8JavascriptCallback( + CefRefPtr[CefV8Value] v8Value, + CefRefPtr[CefV8Context] v8Context) except *: + global g_v8JavascriptCallbacks + global g_v8JavascriptCallbackContexts + global g_v8JavascriptCallbackCount + g_v8JavascriptCallbackCount += 1 + cdef int callbackId = g_v8JavascriptCallbackCount + g_v8JavascriptCallbacks[callbackId] = v8Value + g_v8JavascriptCallbackContexts[callbackId] = v8Context + return callbackId + +cdef CefRefPtr[CefV8Value] GetV8JavascriptCallback( + int callbackId) except *: + global g_v8JavascriptCallbacks + if g_v8JavascriptCallbacks.find(callbackId) == g_v8JavascriptCallbacks.end(): + raise Exception("GetV8JavascriptCallback() failed: invalid callbackId: %s" + % callbackId) + return g_v8JavascriptCallbacks[callbackId] + +cdef CefRefPtr[CefV8Context] GetV8JavascriptCallbackContext( + int callbackId) except *: + global g_v8JavascriptCallbackContexts + if g_v8JavascriptCallbackContexts.find(callbackId) == g_v8JavascriptCallbackContexts.end(): + raise Exception("GetV8JavascriptCallbackContext() failed: invalid callbackId: %s" + % callbackId) + return g_v8JavascriptCallbackContexts[callbackId] + +cdef void DelV8JavascriptCallback( + int callbackId) except *: + global g_v8JavascriptCallbacks + global g_v8JavascriptCallbackContexts + g_v8JavascriptCallbacks.erase(callbackId) + g_v8JavascriptCallbackContexts.erase(callbackId) + +cdef class JavascriptCallback: + cdef int callbackId + + def __init__(self, int callbackId): + assert callbackId, "JavascriptCallback.__init__() failed: callbackId is empty" + self.callbackId = callbackId + + def __dealloc__(self): + DelV8JavascriptCallback(self.callbackId) + + def Call(self, *args): + cdef CefRefPtr[CefV8Value] v8Value = GetV8JavascriptCallback(self.callbackId) + cdef CefRefPtr[CefV8Context] v8Context = GetV8JavascriptCallbackContext(self.callbackId) + cdef CefV8ValueList v8Arguments + cdef CefRefPtr[CefV8Value] v8Retval + cdef CefRefPtr[CefV8Exception] v8Exception + cdef CefV8Exception* v8ExceptionPtr + cdef int i + + # Javascript callback may be kept somewhere and later called from + # a different v8 frame context. Need to enter js v8 context before + # calling PyToV8Value(). + + cdef cpp_bool sameContext = v8Context.get().IsSame(cef_v8_static.GetCurrentContext()) + + if not sameContext: + Debug("JavascriptCallback.Call(): inside a different context, calling v8Context.Enter()") + assert v8Context.get().Enter(), "v8Context.Enter() failed" + + for i in range(0, len(args)): + v8Arguments.push_back(PyToV8Value(args[i], v8Context)) + + if not sameContext: + assert v8Context.get().Exit(), "v8Context.Exit() failed" + + v8Retval = v8Value.get().ExecuteFunctionWithContext( + v8Context, + NULL, + v8Arguments) + + cdef int lineNumber + cdef str message + cdef str scriptResourceName + cdef str sourceLine + cdef str stackTrace + + # This exception should be first caught by V8ContextHandler::OnUncaughtException(). + if v8Value.get().HasException(): + v8Exception = v8Value.get().GetException() + v8ExceptionPtr = v8Exception.get() + lineNumber = v8ExceptionPtr.GetLineNumber() + message = CefToPyString(v8ExceptionPtr.GetMessage()) + scriptResourceName = CefToPyString(v8ExceptionPtr.GetScriptResourceName()) + sourceLine = CefToPyString(v8ExceptionPtr.GetSourceLine()) + stackTrace = FormatJavascriptStackTrace(GetJavascriptStackTrace(100)) + + # TODO: throw exceptions according to execution context (Issue 11), + # TODO: should we call v8ExceptionPtr.ClearException()? What if python + # code does try: except: to catch the exception below, if it's catched then + # js should execute further, like it never happened, and is ClearException() + # for that? + + raise Exception("JavascriptCallback.Call() failed: javascript exception:\n" + "%s.\nOn line %s in %s.\n" + "Source of that line: %s\n\n%s" + % (message, lineNumber, scriptResourceName, sourceLine, stackTrace)) + + if v8Retval == NULL: + raise Exception("JavascriptCallback.Call() failed: ExecuteFunctionWithContext() " + "called incorrectly") + + pyRet = V8ToPyValue(v8Retval, v8Context) + return pyRet + + def GetName(self): + cdef CefRefPtr[CefV8Value] v8Value = GetV8JavascriptCallback(self.callbackId) + cdef CefString cefFuncName + cefFuncName = v8Value.get().GetFunctionName() + return CefToPyString(cefFuncName) diff --git a/cefpython/javascript_callback_cef3.pyx b/cefpython/javascript_callback_cef3.pyx new file mode 100644 index 00000000..eb181fb1 --- /dev/null +++ b/cefpython/javascript_callback_cef3.pyx @@ -0,0 +1,47 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef JavascriptCallback CreateJavascriptCallback(int callbackId, + CefRefPtr[CefBrowser] cefBrowser, object frameId, py_string functionName): + # frameId is int64 + cdef JavascriptCallback jsCallback = JavascriptCallback() + jsCallback.callbackId = callbackId + cdef PyBrowser browser = GetPyBrowser(cefBrowser) + jsCallback.frame = browser.GetFrameByIdentifier(frameId) + jsCallback.functionName = functionName + Debug("Created javascript callback, callbackId=%s, functionName=%s" % \ + (callbackId, functionName)) + return jsCallback + +cdef class JavascriptCallback: + cdef int callbackId + cdef PyFrame frame + cdef py_string functionName + + def Call(self, *args): + # Send process message "ExecuteJavascriptCallback". + if self.frame: + browser = self.frame.GetBrowser() + if browser: + browser.SendProcessMessage( + cef_types.PID_RENDERER, + self.frame.GetIdentifier(), + "ExecuteJavascriptCallback", + [self.callbackId] + list(args)) + else: + Debug("JavascriptCallback.Call() FAILED: browser not found, " \ + "callbackId = %s" % self.callbackId) + else: + Debug("JavascriptCallback.Call() FAILED: frame not found, " \ + "callbackId = %s" % self.callbackId) + + def GetFunctionName(self): + return self.functionName + + def GetName(self): + # DEPRECATED name. + return self.GetFunctionName() + + def GetFrame(self): + return self.frame diff --git a/cefpython/javascript_dialog_handler.pyx b/cefpython/javascript_dialog_handler.pyx new file mode 100644 index 00000000..a2db6908 --- /dev/null +++ b/cefpython/javascript_dialog_handler.pyx @@ -0,0 +1,126 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# enum cef_jsdialog_type_t +JSDIALOGTYPE_ALERT = cef_types.JSDIALOGTYPE_ALERT +JSDIALOGTYPE_CONFIRM = cef_types.JSDIALOGTYPE_CONFIRM +JSDIALOGTYPE_PROMPT = cef_types.JSDIALOGTYPE_PROMPT + +# ----------------------------------------------------------------------------- +# PyJavascriptDialogCallback +# ----------------------------------------------------------------------------- +cdef PyJavascriptDialogCallback CreatePyJavascriptDialogCallback( + CefRefPtr[CefJSDialogCallback] cefCallback): + cdef PyJavascriptDialogCallback pyCallback = PyJavascriptDialogCallback() + pyCallback.cefCallback = cefCallback + return pyCallback + +cdef class PyJavascriptDialogCallback: + cdef CefRefPtr[CefJSDialogCallback] cefCallback + + cpdef py_void Continue(self, py_bool allow, py_string userInput): + self.cefCallback.get().Continue(bool(allow), + PyToCefStringValue(userInput)) +# ----------------------------------------------------------------------------- +# JavascriptDialogHandler +# ----------------------------------------------------------------------------- + +cdef public cpp_bool JavascriptDialogHandler_OnJavascriptDialog( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& origin_url, + const CefString& accept_lang, + cef_types.cef_jsdialog_type_t dialog_type, + const CefString& message_text, + const CefString& default_prompt_text, + CefRefPtr[CefJSDialogCallback] callback, + cpp_bool& suppress_message + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyOriginUrl + cdef py_string pyAcceptLang + cdef py_string pyMessageText + cdef py_string pyDefaultPromptText + cdef PyJavascriptDialogCallback pyCallback + cdef list pySuppressMessage = [] + + cdef object clientCallback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyOriginUrl = CefToPyString(origin_url) + pyAcceptLang = CefToPyString(accept_lang) + pyMessageText = CefToPyString(message_text) + pyDefaultPromptText = CefToPyString(default_prompt_text) + pyCallback = CreatePyJavascriptDialogCallback(callback) + pySuppressMessage = [bool(suppress_message)] + + clientCallback = pyBrowser.GetClientCallback("OnJavascriptDialog") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyOriginUrl, pyAcceptLang, + dialog_type, pyMessageText, pyDefaultPromptText, + pyCallback, pySuppressMessage) + (&suppress_message)[0] = bool(pySuppressMessage[0]) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool JavascriptDialogHandler_OnBeforeUnloadJavascriptDialog( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& message_text, + cpp_bool is_reload, + CefRefPtr[CefJSDialogCallback] callback + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyMessageText + cdef py_bool pyIsReload + cdef PyJavascriptDialogCallback pyCallback + + cdef object clientCallback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyMessageText = CefToPyString(message_text) + pyIsReload = bool(is_reload) + pyCallback = CreatePyJavascriptDialogCallback(callback) + + clientCallback = pyBrowser.GetClientCallback(\ + "OnBeforeUnloadJavascriptDialog") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyMessageText, pyIsReload,\ + pyCallback) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void JavascriptDialogHandler_OnResetJavascriptDialogState( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback(\ + "OnResetJavascriptDialogState") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void JavascriptDialogHandler_OnJavascriptDialogClosed( + CefRefPtr[CefBrowser] cefBrowser, + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnJavascriptDialogClosed") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + diff --git a/cefpython/keyboard_handler_cef1.pyx b/cefpython/keyboard_handler_cef1.pyx new file mode 100644 index 00000000..adcc5178 --- /dev/null +++ b/cefpython/keyboard_handler_cef1.pyx @@ -0,0 +1,42 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +KEYEVENT_RAWKEYDOWN = cef_types.KEYEVENT_RAWKEYDOWN +KEYEVENT_KEYDOWN = cef_types.KEYEVENT_KEYDOWN +KEYEVENT_KEYUP = cef_types.KEYEVENT_KEYUP +KEYEVENT_CHAR = cef_types.KEYEVENT_CHAR + +KEY_NONE = 0 +KEY_SHIFT = cef_types.KEY_SHIFT +KEY_CTRL = cef_types.KEY_CTRL +KEY_ALT = cef_types.KEY_ALT +KEY_META = cef_types.KEY_META +KEY_KEYPAD = cef_types.KEY_KEYPAD + +cdef public cpp_bool KeyboardHandler_OnKeyEvent( + CefRefPtr[CefBrowser] cefBrowser, + cef_types.cef_handler_keyevent_type_t eventType, + int code, + int modifiers, + cpp_bool isSystemKey, + cpp_bool isAfterJavascript + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnKeyEvent") + if callback: + return bool(callback( + pyBrowser, + eventType, + code, + modifiers, + isSystemKey, + isAfterJavascript)) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/keyboard_handler_cef3.pyx b/cefpython/keyboard_handler_cef3.pyx new file mode 100644 index 00000000..47c42e5d --- /dev/null +++ b/cefpython/keyboard_handler_cef3.pyx @@ -0,0 +1,88 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# cef_key_event_type_t +KEYEVENT_RAWKEYDOWN = cef_types.KEYEVENT_RAWKEYDOWN +KEYEVENT_KEYDOWN = cef_types.KEYEVENT_KEYDOWN +KEYEVENT_KEYUP = cef_types.KEYEVENT_KEYUP +KEYEVENT_CHAR = cef_types.KEYEVENT_CHAR + +# cef_event_flags_t +EVENTFLAG_NONE = cef_types.EVENTFLAG_NONE +EVENTFLAG_CAPS_LOCK_ON = cef_types.EVENTFLAG_CAPS_LOCK_ON +EVENTFLAG_SHIFT_DOWN = cef_types.EVENTFLAG_SHIFT_DOWN +EVENTFLAG_CONTROL_DOWN = cef_types.EVENTFLAG_CONTROL_DOWN +EVENTFLAG_ALT_DOWN = cef_types.EVENTFLAG_ALT_DOWN +EVENTFLAG_LEFT_MOUSE_BUTTON = cef_types.EVENTFLAG_LEFT_MOUSE_BUTTON +EVENTFLAG_MIDDLE_MOUSE_BUTTON = cef_types.EVENTFLAG_MIDDLE_MOUSE_BUTTON +EVENTFLAG_RIGHT_MOUSE_BUTTON = cef_types.EVENTFLAG_RIGHT_MOUSE_BUTTON +# Mac OS-X command key. +EVENTFLAG_COMMAND_DOWN = cef_types.EVENTFLAG_COMMAND_DOWN +EVENTFLAG_NUM_LOCK_ON = cef_types.EVENTFLAG_NUM_LOCK_ON +EVENTFLAG_IS_KEY_PAD = cef_types.EVENTFLAG_IS_KEY_PAD +EVENTFLAG_IS_LEFT = cef_types.EVENTFLAG_IS_LEFT +EVENTFLAG_IS_RIGHT = cef_types.EVENTFLAG_IS_RIGHT + +cdef dict CefToPyKeyEvent(const cef_types.CefKeyEvent& cefKeyEvent): + pyKeyEvent = { + "type": cefKeyEvent.type, + "modifiers": cefKeyEvent.modifiers, + "windows_key_code": cefKeyEvent.windows_key_code, + "native_key_code": cefKeyEvent.native_key_code, + "is_system_key": cefKeyEvent.is_system_key, + "character": cefKeyEvent.character, + "unmodified_character": cefKeyEvent.unmodified_character, + "focus_on_editable_field": cefKeyEvent.focus_on_editable_field + } + return pyKeyEvent + +cdef public cpp_bool KeyboardHandler_OnPreKeyEvent( + CefRefPtr[CefBrowser] cefBrowser, + const cef_types.CefKeyEvent& cefEvent, + cef_types.CefEventHandle cefEventHandle, + cpp_bool* cefIsKeyboardShortcut + ) except * with gil: + cdef PyBrowser pyBrowser + cdef dict pyEvent + cdef list pyIsKeyboardShortcutOut + cdef py_bool returnValue + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyEvent = CefToPyKeyEvent(cefEvent) + pyIsKeyboardShortcutOut = [cefIsKeyboardShortcut[0]] + callback = pyBrowser.GetClientCallback("OnPreKeyEvent") + if callback: + returnValue = callback(pyBrowser, pyEvent, + PyLong_FromVoidPtr(cefEventHandle), + pyIsKeyboardShortcutOut) + cefIsKeyboardShortcut[0] = \ + bool(pyIsKeyboardShortcutOut[0]) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool KeyboardHandler_OnKeyEvent( + CefRefPtr[CefBrowser] cefBrowser, + const cef_types.CefKeyEvent& cefEvent, + cef_types.CefEventHandle cefEventHandle + ) except * with gil: + cdef PyBrowser pyBrowser + cdef dict pyEvent + cdef py_bool returnValue + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyEvent = CefToPyKeyEvent(cefEvent) + callback = pyBrowser.GetClientCallback("OnKeyEvent") + if callback: + returnValue = callback(pyBrowser, pyEvent, + PyLong_FromVoidPtr(cefEventHandle)) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/lifespan_handler_cef1.pyx b/cefpython/lifespan_handler_cef1.pyx new file mode 100644 index 00000000..8edee66d --- /dev/null +++ b/cefpython/lifespan_handler_cef1.pyx @@ -0,0 +1,64 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public cpp_bool LifespanHandler_DoClose( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("DoClose") + if callback: + return bool(callback(pyBrowser)) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LifespanHandler_OnAfterCreated( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + # Popup windows has no mouse/keyboard focus (Issue 14). + pyBrowser.SetFocus(True) + callback = pyBrowser.GetClientCallback("OnAfterCreated") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LifespanHandler_OnBeforeClose( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnBeforeClose") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool LifespanHandler_RunModal( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("RunModal") + if callback: + return bool(callback(pyBrowser)) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/lifespan_handler_cef3.pyx b/cefpython/lifespan_handler_cef3.pyx new file mode 100644 index 00000000..b741c218 --- /dev/null +++ b/cefpython/lifespan_handler_cef3.pyx @@ -0,0 +1,106 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public cpp_bool LifespanHandler_OnBeforePopup( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + const CefString& targetUrl, + const CefString& targetFrameName, + const int popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr[CefClient]& client, + CefBrowserSettings& settings, + cpp_bool* noJavascriptAccess + ) except * with gil: + # Empty place-holders: popupFeatures, client. + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame, + cdef py_string pyTargetUrl + cdef py_string pyTargetFrameName + cdef list pyNoJavascriptAccess # out bool pyNoJavascriptAccess[0] + cdef list pyWindowInfo + cdef list pyBrowserSettings + cdef object callback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyTargetUrl = CefToPyString(targetUrl) + pyTargetFrameName = CefToPyString(targetFrameName) + pyNoJavascriptAccess = [noJavascriptAccess[0]] + pyWindowInfo = [] + pyBrowserSettings = [] + callback = pyBrowser.GetClientCallback("OnBeforePopup") + if callback: + returnValue = bool(callback(pyBrowser, pyFrame, pyTargetUrl, + pyTargetFrameName, None, pyWindowInfo, None, + pyBrowserSettings, pyNoJavascriptAccess)) + noJavascriptAccess[0] = bool(pyNoJavascriptAccess[0]) + if len(pyBrowserSettings): + SetBrowserSettings(pyBrowserSettings[0], &settings) + if len(pyWindowInfo): + SetCefWindowInfo(windowInfo, pyWindowInfo[0]) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LifespanHandler_OnAfterCreated( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = GetGlobalClientCallback("OnAfterCreated") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool LifespanHandler_RunModal( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("RunModal") + if callback: + return bool(callback(pyBrowser)) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool LifespanHandler_DoClose( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("DoClose") + if callback: + return bool(callback(pyBrowser)) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LifespanHandler_OnBeforeClose( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnBeforeClose") + if callback: + callback(pyBrowser) + RemovePythonCallbacksForBrowser(pyBrowser.GetIdentifier()) + RemovePyFramesForBrowser(pyBrowser.GetIdentifier()) + RemovePyBrowser(pyBrowser.GetIdentifier()) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/load_handler_cef1.pyx b/cefpython/load_handler_cef1.pyx new file mode 100644 index 00000000..cdefc65b --- /dev/null +++ b/cefpython/load_handler_cef1.pyx @@ -0,0 +1,69 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void LoadHandler_OnLoadEnd( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + int httpStatusCode + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + callback = pyBrowser.GetClientCallback("OnLoadEnd") + if callback: + callback(pyBrowser, pyFrame, httpStatusCode) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LoadHandler_OnLoadStart( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + callback = pyBrowser.GetClientCallback("OnLoadStart") + if callback: + callback(pyBrowser, pyFrame) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool LoadHandler_OnLoadError( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + cef_types.cef_handler_errorcode_t cefErrorCode, + CefString& cefFailedUrl, + CefString& cefErrorText + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef str pyFailedUrl + cdef object callback + cdef list errorText + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyFailedUrl = CefToPyString(cefFailedUrl) + callback = pyBrowser.GetClientCallback("OnLoadError") + if callback: + errorText = [""] + ret = callback( + pyBrowser, pyFrame, cefErrorCode, pyFailedUrl, errorText) + if ret: + PyToCefString(errorText[0], cefErrorText) + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/load_handler_cef3.pyx b/cefpython/load_handler_cef3.pyx new file mode 100644 index 00000000..88b7a922 --- /dev/null +++ b/cefpython/load_handler_cef3.pyx @@ -0,0 +1,85 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void LoadHandler_OnLoadingStateChange( + CefRefPtr[CefBrowser] cefBrowser, + cpp_bool isLoading, + cpp_bool canGoBack, + cpp_bool canGoForward + ) except * with gil: + cdef PyBrowser pyBrowser + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnLoadingStateChange") + if callback: + callback(pyBrowser, isLoading, canGoBack, canGoForward) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LoadHandler_OnLoadStart( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + clientCallback = pyBrowser.GetClientCallback("OnLoadStart") + if clientCallback: + clientCallback(pyBrowser, pyFrame) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LoadHandler_OnLoadEnd( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + int httpStatusCode + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + clientCallback = pyBrowser.GetClientCallback("OnLoadEnd") + if clientCallback: + clientCallback(pyBrowser, pyFrame, httpStatusCode) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void LoadHandler_OnLoadError( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + cef_types.cef_errorcode_t cefErrorCode, + const CefString& cefErrorText, + const CefString& cefFailedUrl + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef list errorTextOut + cdef object clientCallback + try: + # If webpage loading or file download is aborted by user + # the error code will be ERR_ABORTED. In such cases calls + # to OnLoadError should be ignored and not handled by user + # scripts. The wxpython example implements such behavior. + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + errorTextOut = [CefToPyString(cefErrorText)] + clientCallback = pyBrowser.GetClientCallback("OnLoadError") + if clientCallback: + clientCallback( + pyBrowser, pyFrame, cefErrorCode, errorTextOut, + CefToPyString(cefFailedUrl)) + # Providing custom error messsage not yet supported in CEF 3. + # | PyToCefString(errorTextOut[0], cefErrorText) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/network_error_cef1.pyx b/cefpython/network_error_cef1.pyx new file mode 100644 index 00000000..332c2a4d --- /dev/null +++ b/cefpython/network_error_cef1.pyx @@ -0,0 +1,54 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Network error constants. +ERR_NONE = 0 +ERR_FAILED = cef_types.ERR_FAILED +ERR_ABORTED = cef_types.ERR_ABORTED +ERR_INVALID_ARGUMENT = cef_types.ERR_INVALID_ARGUMENT +ERR_INVALID_HANDLE = cef_types.ERR_INVALID_HANDLE +ERR_FILE_NOT_FOUND = cef_types.ERR_FILE_NOT_FOUND +ERR_TIMED_OUT = cef_types.ERR_TIMED_OUT +ERR_FILE_TOO_BIG = cef_types.ERR_FILE_TOO_BIG +ERR_UNEXPECTED = cef_types.ERR_UNEXPECTED +ERR_ACCESS_DENIED = cef_types.ERR_ACCESS_DENIED +ERR_NOT_IMPLEMENTED = cef_types.ERR_NOT_IMPLEMENTED +ERR_CONNECTION_CLOSED = cef_types.ERR_CONNECTION_CLOSED +ERR_CONNECTION_RESET = cef_types.ERR_CONNECTION_RESET +ERR_CONNECTION_REFUSED = cef_types.ERR_CONNECTION_REFUSED +ERR_CONNECTION_ABORTED = cef_types.ERR_CONNECTION_ABORTED +ERR_CONNECTION_FAILED = cef_types.ERR_CONNECTION_FAILED +ERR_NAME_NOT_RESOLVED = cef_types.ERR_NAME_NOT_RESOLVED +ERR_INTERNET_DISCONNECTED = cef_types.ERR_INTERNET_DISCONNECTED +ERR_SSL_PROTOCOL_ERROR = cef_types.ERR_SSL_PROTOCOL_ERROR +ERR_ADDRESS_INVALID = cef_types.ERR_ADDRESS_INVALID +ERR_ADDRESS_UNREACHABLE = cef_types.ERR_ADDRESS_UNREACHABLE +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = cef_types.ERR_SSL_CLIENT_AUTH_CERT_NEEDED +ERR_TUNNEL_CONNECTION_FAILED = cef_types.ERR_TUNNEL_CONNECTION_FAILED +ERR_NO_SSL_VERSIONS_ENABLED = cef_types.ERR_NO_SSL_VERSIONS_ENABLED +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = cef_types.ERR_SSL_VERSION_OR_CIPHER_MISMATCH +ERR_SSL_RENEGOTIATION_REQUESTED = cef_types.ERR_SSL_RENEGOTIATION_REQUESTED +ERR_CERT_COMMON_NAME_INVALID = cef_types.ERR_CERT_COMMON_NAME_INVALID +ERR_CERT_DATE_INVALID = cef_types.ERR_CERT_DATE_INVALID +ERR_CERT_AUTHORITY_INVALID = cef_types.ERR_CERT_AUTHORITY_INVALID +ERR_CERT_CONTAINS_ERRORS = cef_types.ERR_CERT_CONTAINS_ERRORS +ERR_CERT_NO_REVOCATION_MECHANISM = cef_types.ERR_CERT_NO_REVOCATION_MECHANISM +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = cef_types.ERR_CERT_UNABLE_TO_CHECK_REVOCATION +ERR_CERT_REVOKED = cef_types.ERR_CERT_REVOKED +ERR_CERT_INVALID = cef_types.ERR_CERT_INVALID +ERR_CERT_END = cef_types.ERR_CERT_END +ERR_INVALID_URL = cef_types.ERR_INVALID_URL +ERR_DISALLOWED_URL_SCHEME = cef_types.ERR_DISALLOWED_URL_SCHEME +ERR_UNKNOWN_URL_SCHEME = cef_types.ERR_UNKNOWN_URL_SCHEME +ERR_TOO_MANY_REDIRECTS = cef_types.ERR_TOO_MANY_REDIRECTS +ERR_UNSAFE_REDIRECT = cef_types.ERR_UNSAFE_REDIRECT +ERR_UNSAFE_PORT = cef_types.ERR_UNSAFE_PORT +ERR_INVALID_RESPONSE = cef_types.ERR_INVALID_RESPONSE +ERR_INVALID_CHUNKED_ENCODING = cef_types.ERR_INVALID_CHUNKED_ENCODING +ERR_METHOD_NOT_SUPPORTED = cef_types.ERR_METHOD_NOT_SUPPORTED +ERR_UNEXPECTED_PROXY_AUTH = cef_types.ERR_UNEXPECTED_PROXY_AUTH +ERR_EMPTY_RESPONSE = cef_types.ERR_EMPTY_RESPONSE +ERR_RESPONSE_HEADERS_TOO_BIG = cef_types.ERR_RESPONSE_HEADERS_TOO_BIG +ERR_CACHE_MISS = cef_types.ERR_CACHE_MISS +ERR_INSECURE_RESPONSE = cef_types.ERR_INSECURE_RESPONSE diff --git a/cefpython/network_error_cef3.pyx b/cefpython/network_error_cef3.pyx new file mode 100644 index 00000000..cb8b5e95 --- /dev/null +++ b/cefpython/network_error_cef3.pyx @@ -0,0 +1,54 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Network error constants. +ERR_NONE = cef_types.ERR_NONE +ERR_FAILED = cef_types.ERR_FAILED +ERR_ABORTED = cef_types.ERR_ABORTED +ERR_INVALID_ARGUMENT = cef_types.ERR_INVALID_ARGUMENT +ERR_INVALID_HANDLE = cef_types.ERR_INVALID_HANDLE +ERR_FILE_NOT_FOUND = cef_types.ERR_FILE_NOT_FOUND +ERR_TIMED_OUT = cef_types.ERR_TIMED_OUT +ERR_FILE_TOO_BIG = cef_types.ERR_FILE_TOO_BIG +ERR_UNEXPECTED = cef_types.ERR_UNEXPECTED +ERR_ACCESS_DENIED = cef_types.ERR_ACCESS_DENIED +ERR_NOT_IMPLEMENTED = cef_types.ERR_NOT_IMPLEMENTED +ERR_CONNECTION_CLOSED = cef_types.ERR_CONNECTION_CLOSED +ERR_CONNECTION_RESET = cef_types.ERR_CONNECTION_RESET +ERR_CONNECTION_REFUSED = cef_types.ERR_CONNECTION_REFUSED +ERR_CONNECTION_ABORTED = cef_types.ERR_CONNECTION_ABORTED +ERR_CONNECTION_FAILED = cef_types.ERR_CONNECTION_FAILED +ERR_NAME_NOT_RESOLVED = cef_types.ERR_NAME_NOT_RESOLVED +ERR_INTERNET_DISCONNECTED = cef_types.ERR_INTERNET_DISCONNECTED +ERR_SSL_PROTOCOL_ERROR = cef_types.ERR_SSL_PROTOCOL_ERROR +ERR_ADDRESS_INVALID = cef_types.ERR_ADDRESS_INVALID +ERR_ADDRESS_UNREACHABLE = cef_types.ERR_ADDRESS_UNREACHABLE +ERR_SSL_CLIENT_AUTH_CERT_NEEDED = cef_types.ERR_SSL_CLIENT_AUTH_CERT_NEEDED +ERR_TUNNEL_CONNECTION_FAILED = cef_types.ERR_TUNNEL_CONNECTION_FAILED +ERR_NO_SSL_VERSIONS_ENABLED = cef_types.ERR_NO_SSL_VERSIONS_ENABLED +ERR_SSL_VERSION_OR_CIPHER_MISMATCH = cef_types.ERR_SSL_VERSION_OR_CIPHER_MISMATCH +ERR_SSL_RENEGOTIATION_REQUESTED = cef_types.ERR_SSL_RENEGOTIATION_REQUESTED +ERR_CERT_COMMON_NAME_INVALID = cef_types.ERR_CERT_COMMON_NAME_INVALID +ERR_CERT_DATE_INVALID = cef_types.ERR_CERT_DATE_INVALID +ERR_CERT_AUTHORITY_INVALID = cef_types.ERR_CERT_AUTHORITY_INVALID +ERR_CERT_CONTAINS_ERRORS = cef_types.ERR_CERT_CONTAINS_ERRORS +ERR_CERT_NO_REVOCATION_MECHANISM = cef_types.ERR_CERT_NO_REVOCATION_MECHANISM +ERR_CERT_UNABLE_TO_CHECK_REVOCATION = cef_types.ERR_CERT_UNABLE_TO_CHECK_REVOCATION +ERR_CERT_REVOKED = cef_types.ERR_CERT_REVOKED +ERR_CERT_INVALID = cef_types.ERR_CERT_INVALID +ERR_CERT_END = cef_types.ERR_CERT_END +ERR_INVALID_URL = cef_types.ERR_INVALID_URL +ERR_DISALLOWED_URL_SCHEME = cef_types.ERR_DISALLOWED_URL_SCHEME +ERR_UNKNOWN_URL_SCHEME = cef_types.ERR_UNKNOWN_URL_SCHEME +ERR_TOO_MANY_REDIRECTS = cef_types.ERR_TOO_MANY_REDIRECTS +ERR_UNSAFE_REDIRECT = cef_types.ERR_UNSAFE_REDIRECT +ERR_UNSAFE_PORT = cef_types.ERR_UNSAFE_PORT +ERR_INVALID_RESPONSE = cef_types.ERR_INVALID_RESPONSE +ERR_INVALID_CHUNKED_ENCODING = cef_types.ERR_INVALID_CHUNKED_ENCODING +ERR_METHOD_NOT_SUPPORTED = cef_types.ERR_METHOD_NOT_SUPPORTED +ERR_UNEXPECTED_PROXY_AUTH = cef_types.ERR_UNEXPECTED_PROXY_AUTH +ERR_EMPTY_RESPONSE = cef_types.ERR_EMPTY_RESPONSE +ERR_RESPONSE_HEADERS_TOO_BIG = cef_types.ERR_RESPONSE_HEADERS_TOO_BIG +ERR_CACHE_MISS = cef_types.ERR_CACHE_MISS +ERR_INSECURE_RESPONSE = cef_types.ERR_INSECURE_RESPONSE diff --git a/cefpython/paint_buffer_cef1.pyx b/cefpython/paint_buffer_cef1.pyx new file mode 100644 index 00000000..9f43b709 --- /dev/null +++ b/cefpython/paint_buffer_cef1.pyx @@ -0,0 +1,50 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PaintBuffer CreatePaintBuffer(void* buffer, int width, int height): + cdef PaintBuffer paintBuffer = PaintBuffer() + paintBuffer.buffer = buffer + paintBuffer.width = width + paintBuffer.height = height + paintBuffer.length = width*height*4 + return paintBuffer + +cdef class PaintBuffer: + cdef void* buffer + cdef int width + cdef int height + cdef Py_ssize_t length + + cpdef long long GetIntPointer(self) except *: + return self.buffer + + cpdef object GetString(self, str mode="bgra", str origin="top-left"): + cdef void* dest + cdef py_bool dest_alloced = False + cdef object ret + + origin = origin.lower() + mode = mode.lower() + assert origin in ("top-left", "bottom-left"), "Invalid origin" + assert mode in ("bgra", "rgba"), "Invalid mode" + + if mode == "rgba": + if not dest_alloced: + dest = malloc(self.length) + dest_alloced = True + SwapBufferFromBgraToRgba(dest, self.buffer, self.width, + self.height) + + if origin == "bottom-left": + if not dest_alloced: + dest = malloc(self.length) + dest_alloced = True + FlipBufferUpsideDown(dest, self.buffer, self.width, self.height) + + if dest_alloced: + ret = (dest)[:self.length] + free(dest) + return ret + else: + return (self.buffer)[:self.length] diff --git a/cefpython/paint_buffer_cef3.pyx b/cefpython/paint_buffer_cef3.pyx new file mode 100644 index 00000000..a28eb7a6 --- /dev/null +++ b/cefpython/paint_buffer_cef3.pyx @@ -0,0 +1,54 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PaintBuffer CreatePaintBuffer(const void* buffer, int width, int height): + cdef PaintBuffer paintBuffer = PaintBuffer() + paintBuffer.buffer = buffer + paintBuffer.width = width + paintBuffer.height = height + paintBuffer.length = width*height*4 + return paintBuffer + +cdef class PaintBuffer: + cdef const void* buffer + cdef int width + cdef int height + cdef Py_ssize_t length + + cpdef long long GetIntPointer(self) except *: + return self.buffer + + cpdef object GetString(self, str mode="bgra", str origin="top-left"): + cdef void* dest + cdef py_bool dest_alloced = False + cdef object ret + + origin = origin.lower() + mode = mode.lower() + assert origin in ("top-left", "bottom-left"), "Invalid origin" + assert mode in ("bgra", "rgba"), "Invalid mode" + + # To get rid of a Cython warning: + # | ‘__pyx_v_dest’ may be used uninitialized in this function + dest = malloc(0) + + if mode == "rgba": + if not dest_alloced: + dest = malloc(self.length) + dest_alloced = True + SwapBufferFromBgraToRgba(dest, self.buffer, self.width, + self.height) + + if origin == "bottom-left": + if not dest_alloced: + dest = malloc(self.length) + dest_alloced = True + FlipBufferUpsideDown(dest, self.buffer, self.width, self.height) + + if dest_alloced: + ret = (dest)[:self.length] + free(dest) + return ret + else: + return (self.buffer)[:self.length] diff --git a/cefpython/process_message_utils.pyx b/cefpython/process_message_utils.pyx new file mode 100644 index 00000000..f6a1b2de --- /dev/null +++ b/cefpython/process_message_utils.pyx @@ -0,0 +1,339 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# CefListValue->SetXxxx() functions need first param to be be cast +# to (int) because GetSize() returns size_t and generates a warning +# when compiling on VS2008 for x64 platform. Issue reported here: +# https://code.google.com/p/cefpython/issues/detail?id=165 +# Here in pyx you also need to convert Py_ssize_t returned by +# enumerate(), to an int. + +# ----------------------------------------------------------------------------- +# CEF values to Python values +# ----------------------------------------------------------------------------- + +cdef object CheckForCefPythonMessageHash(CefRefPtr[CefBrowser] cefBrowser, + py_string pyString): + # A javascript callback from the Renderer process is sent as a string. + # TODO: this could be sent using CefBinaryNamedString in the future, + # see this topic "Sending custom data types using process messaging": + # http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10881 + cdef py_string cefPythonMessageHash = "####cefpython####" + cdef JavascriptCallback jsCallback + cdef py_string jsonData + cdef object message + if pyString.startswith(cefPythonMessageHash): + jsonData = pyString[len(cefPythonMessageHash):] + message = json.loads(jsonData) + if message and type(message) == dict and ("what" in message) \ + and message["what"] == "javascript-callback": + jsCallback = CreateJavascriptCallback( + message["callbackId"], cefBrowser, + message["frameId"], message["functionName"]) + return jsCallback + return pyString + +cdef list CefListValueToPyList( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefListValue] cefListValue, + int nestingLevel=0): + assert cefListValue.get().IsValid(), "cefListValue is invalid" + if nestingLevel > 8: + raise Exception("CefListValueToPyList(): max nesting level (8)" + " exceeded") + cdef int index + cdef int size = int(cefListValue.get().GetSize()) + cdef cef_types.cef_value_type_t valueType + cdef list ret = [] + cdef CefRefPtr[CefBinaryValue] binaryValue + cdef cef_types.uint32 uint32_value + cdef cef_types.int64 int64_value + cdef object originallyString + for index in range(0, size): + valueType = cefListValue.get().GetType(index) + if valueType == cef_types.VTYPE_NULL: + ret.append(None) + elif valueType == cef_types.VTYPE_BOOL: + ret.append(bool(cefListValue.get().GetBool(index))) + elif valueType == cef_types.VTYPE_INT: + ret.append(cefListValue.get().GetInt(index)) + elif valueType == cef_types.VTYPE_DOUBLE: + ret.append(cefListValue.get().GetDouble(index)) + elif valueType == cef_types.VTYPE_STRING: + originallyString = CefToPyString( + cefListValue.get().GetString(index)) + originallyString = CheckForCefPythonMessageHash(cefBrowser, + originallyString) + ret.append(originallyString) + elif valueType == cef_types.VTYPE_DICTIONARY: + ret.append(CefDictionaryValueToPyDict( + cefBrowser, + cefListValue.get().GetDictionary(index), + nestingLevel + 1)) + elif valueType == cef_types.VTYPE_LIST: + ret.append(CefListValueToPyList( + cefBrowser, + cefListValue.get().GetList(index), + nestingLevel + 1)) + elif valueType == cef_types.VTYPE_BINARY: + binaryValue = cefListValue.get().GetBinary(index) + if binaryValue.get().GetSize() == sizeof(uint32_value): + binaryValue.get().GetData( + &uint32_value, sizeof(uint32_value), 0) + ret.append(uint32_value) + elif binaryValue.get().GetSize() == sizeof(int64_value): + binaryValue.get().GetData( + &int64_value, sizeof(int64_value), 0) + ret.append(int64_value) + else: + raise Exception("Unknown binary value, size=%s" % \ + binaryValue.get().GetSize()) + else: + raise Exception("Unknown value type=%s" % valueType) + return ret + +cdef dict CefDictionaryValueToPyDict( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefDictionaryValue] cefDictionaryValue, + int nestingLevel=0): + assert cefDictionaryValue.get().IsValid(), "cefDictionaryValue is invalid" + if nestingLevel > 8: + raise Exception("CefDictionaryValueToPyDict(): max nesting level (8)" + " exceeded") + cdef cpp_vector[CefString] keyList + cefDictionaryValue.get().GetKeys(keyList) + cdef cef_types.cef_value_type_t valueType + cdef dict ret = {} + cdef cpp_vector[CefString].iterator iterator = keyList.begin() + cdef CefString cefKey + cdef py_string pyKey + cdef CefRefPtr[CefBinaryValue] binaryValue + cdef cef_types.uint32 uint32_value + cdef cef_types.int64 int64_value + cdef object originallyString + while iterator != keyList.end(): + cefKey = deref(iterator) + pyKey = CefToPyString(cefKey) + preinc(iterator) + valueType = cefDictionaryValue.get().GetType(cefKey) + if valueType == cef_types.VTYPE_NULL: + ret[pyKey] = None + elif valueType == cef_types.VTYPE_BOOL: + ret[pyKey] = bool(cefDictionaryValue.get().GetBool(cefKey)) + elif valueType == cef_types.VTYPE_INT: + ret[pyKey] = cefDictionaryValue.get().GetInt(cefKey) + elif valueType == cef_types.VTYPE_DOUBLE: + ret[pyKey] = cefDictionaryValue.get().GetDouble(cefKey) + elif valueType == cef_types.VTYPE_STRING: + originallyString = CefToPyString( + cefDictionaryValue.get().GetString(cefKey)) + originallyString = CheckForCefPythonMessageHash(cefBrowser, + originallyString) + ret[pyKey] = originallyString + elif valueType == cef_types.VTYPE_DICTIONARY: + ret[pyKey] = CefDictionaryValueToPyDict( + cefBrowser, + cefDictionaryValue.get().GetDictionary(cefKey), + nestingLevel + 1) + elif valueType == cef_types.VTYPE_LIST: + ret[pyKey] = CefListValueToPyList( + cefBrowser, + cefDictionaryValue.get().GetList(cefKey), + nestingLevel + 1) + elif valueType == cef_types.VTYPE_BINARY: + binaryValue = cefDictionaryValue.get().GetBinary(cefKey) + if binaryValue.get().GetSize() == sizeof(uint32_value): + binaryValue.get().GetData( + &uint32_value, sizeof(uint32_value), 0) + ret[pyKey] = uint32_value + elif binaryValue.get().GetSize() == sizeof(int64_value): + binaryValue.get().GetData( + &int64_value, sizeof(int64_value), 0) + ret[pyKey] = int64_value + else: + raise Exception("Unknown binary value, size=%s" % \ + binaryValue.get().GetSize()) + else: + raise Exception("Unknown value type = %s" % valueType) + return ret + +# ----------------------------------------------------------------------------- +# Python values to CEF values +# ----------------------------------------------------------------------------- + +cdef CefRefPtr[CefListValue] PyListToCefListValue( + int browserId, + object frameId, + list pyList, + int nestingLevel=0) except *: + if nestingLevel > 8: + raise Exception("PyListToCefListValue(): max nesting level (8)" + " exceeded") + cdef type valueType + cdef CefRefPtr[CefListValue] ret = CefListValue_Create() + cdef CefRefPtr[CefBinaryValue] binaryValue + cdef int index + for index_size_t, value in enumerate(pyList): + index = int(index_size_t) + valueType = type(value) + if valueType == type(None): + ret.get().SetNull(index) + elif valueType == bool: + ret.get().SetBool(index, bool(value)) + elif valueType == int: + ret.get().SetInt(index, int(value)) + elif valueType == long: + # Int32 range is -2147483648..2147483647, we've increased the + # minimum size by one as Cython was throwing a warning: + # "unary minus operator applied to unsigned type, result still + # unsigned". + if value <= 2147483647 and value >= -2147483647: + ret.get().SetInt(index, int(value)) + else: + # Long values become strings. + ret.get().SetString(index, PyToCefStringValue(str(value))) + elif valueType == float: + ret.get().SetDouble(index, float(value)) + elif valueType == bytes or valueType == str \ + or (PY_MAJOR_VERSION < 3 and valueType == unicode): + # The unicode type is not defined in Python 3. + ret.get().SetString(index, PyToCefStringValue(str(value))) + elif valueType == dict: + ret.get().SetDictionary(index, PyDictToCefDictionaryValue( + browserId, frameId, value, nestingLevel + 1)) + elif valueType == list or valueType == tuple: + if valueType == tuple: + value = list(value) + ret.get().SetList(index, PyListToCefListValue( + browserId, frameId, value, nestingLevel + 1)) + elif IsFunctionOrMethod(valueType): + ret.get().SetBinary(index, PutPythonCallback( + browserId, frameId, value)) + else: + # Raising an exception probably not a good idea, why + # terminate application when we can cast it to string, + # the data may contain some non-standard object that is + # probably redundant, but casting to string will do no harm. + # This will handle the "type" type. + ret.get().SetString(index, PyToCefStringValue(str(value))) + return ret + +cdef void PyListToExistingCefListValue( + int browserId, + object frameId, + list pyList, + CefRefPtr[CefListValue] cefListValue, + int nestingLevel=0) except *: + # When sending process messages you must use an existing + # CefListValue, see browser.pyx > SendProcessMessage(). + if nestingLevel > 8: + raise Exception("PyListToCefListValue(): max nesting level (8)" + " exceeded") + cdef type valueType + cdef CefRefPtr[CefListValue] newCefListValue + cdef int index + for index_size_t, value in enumerate(pyList): + index = int(index_size_t) + valueType = type(value) + if valueType == type(None): + cefListValue.get().SetNull(index) + elif valueType == bool: + cefListValue.get().SetBool(index, bool(value)) + elif valueType == int: + cefListValue.get().SetInt(index, int(value)) + elif valueType == long: + # Int32 range is -2147483648..2147483647, we've increased the + # minimum size by one as Cython was throwing a warning: + # "unary minus operator applied to unsigned type, result still + # unsigned". + if value <= 2147483647 and value >= -2147483647: + cefListValue.get().SetInt(index, int(value)) + else: + # Long values become strings. + cefListValue.get().SetString(index, PyToCefStringValue(str( + value))) + elif valueType == float: + cefListValue.get().SetDouble(index, float(value)) + elif valueType == bytes or valueType == str \ + or (PY_MAJOR_VERSION < 3 and valueType == unicode): + # The unicode type is not defined in Python 3. + cefListValue.get().SetString(index, PyToCefStringValue(str(value))) + elif valueType == dict: + cefListValue.get().SetDictionary(index, PyDictToCefDictionaryValue( + browserId, frameId, value, nestingLevel + 1)) + elif valueType == list or valueType == tuple: + if valueType == tuple: + value = list(value) + newCefListValue = CefListValue_Create() + PyListToExistingCefListValue(browserId, frameId, value, + newCefListValue, nestingLevel + 1) + cefListValue.get().SetList(index, newCefListValue) + elif IsFunctionOrMethod(valueType): + cefListValue.get().SetBinary(index, PutPythonCallback( + browserId, frameId, value)) + else: + # Raising an exception probably not a good idea, why + # terminate application when we can cast it to string, + # the data may contain some non-standard object that is + # probably redundant, but casting to string will do no harm. + # This will handle the "type" type. + cefListValue.get().SetString(index, PyToCefStringValue(str(value))) + +cdef CefRefPtr[CefDictionaryValue] PyDictToCefDictionaryValue( + int browserId, + object frameId, + dict pyDict, + int nestingLevel=0) except *: + if nestingLevel > 8: + raise Exception("PyDictToCefDictionaryValue(): max nesting level (8)" + " exceeded") + cdef type valueType + cdef CefRefPtr[CefDictionaryValue] ret = CefDictionaryValue_Create() + cdef CefString cefKey + cdef object value + for pyKey in pyDict: + value = pyDict[pyKey] + valueType = type(value) + PyToCefString(pyKey, cefKey) + if valueType == type(None): + ret.get().SetNull(cefKey) + elif valueType == bool: + ret.get().SetBool(cefKey, bool(value)) + elif valueType == int: + ret.get().SetInt(cefKey, int(value)) + elif valueType == long: + # Int32 range is -2147483648..2147483647, we've increased the + # minimum size by one as Cython was throwing a warning: + # "unary minus operator applied to unsigned type, result still + # unsigned". + if value <= 2147483647 and value >= -2147483647: + ret.get().SetInt(cefKey, int(value)) + else: + # Long values become strings. + ret.get().SetString(cefKey, PyToCefStringValue(str(value))) + elif valueType == float: + ret.get().SetDouble(cefKey, float(value)) + elif valueType == bytes or valueType == str \ + or (PY_MAJOR_VERSION < 3 and valueType == unicode): + # The unicode type is not defined in Python 3. + ret.get().SetString(cefKey, PyToCefStringValue(str(value))) + elif valueType == dict: + ret.get().SetDictionary(cefKey, PyDictToCefDictionaryValue( + browserId, frameId, value, nestingLevel + 1)) + elif valueType == list or valueType == tuple: + if valueType == tuple: + value = list(value) + ret.get().SetList(cefKey, PyListToCefListValue( + browserId, frameId, value, nestingLevel + 1)) + elif IsFunctionOrMethod(valueType): + ret.get().SetBinary(cefKey, PutPythonCallback( + browserId, frameId, value)) + else: + # Raising an exception probably not a good idea, why + # terminate application when we can cast it to string, + # the data may contain some non-standard object that is + # probably redundant, but casting to string will do no harm. + # This will handle the "type" type. + ret.get().SetString(cefKey, PyToCefStringValue(str(value))) + return ret diff --git a/cefpython/python_callback_cef1.pyx b/cefpython/python_callback_cef1.pyx new file mode 100644 index 00000000..602d0f4d --- /dev/null +++ b/cefpython/python_callback_cef1.pyx @@ -0,0 +1,32 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef dict g_PythonCallbacks = {} +# Next callbackId. +cdef int g_PythonCallbackCount = 0 + +cpdef int PutPythonCallback( + object pythonCallback + ) except *: + # Called from v8utils.pyx > PyToV8Value(). + global g_PythonCallbacks + global g_PythonCallbackCount + g_PythonCallbackCount += 1 + callbackId = g_PythonCallbackCount + g_PythonCallbacks[callbackId] = pythonCallback + return callbackId + +cpdef object GetPythonCallback(int callbackId): + global g_PythonCallbacks + if callbackId not in g_PythonCallbacks: + raise Exception("GetPythonCallback() failed: invalid callbackId: %s" % callbackId) + return g_PythonCallbacks[callbackId] + +cdef void RemovePythonCallback( + int callbackId + ) except * with gil: + # Called from v8function_handler.h > ~V8FunctionHandler(). + # Added "with gil" as it's called from C++. + global g_PythonCallbacks + del g_PythonCallbacks[callbackId] diff --git a/cefpython/python_callback_cef3.pyx b/cefpython/python_callback_cef3.pyx new file mode 100644 index 00000000..c28d4bc8 --- /dev/null +++ b/cefpython/python_callback_cef3.pyx @@ -0,0 +1,93 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef int g_pythonCallbackMaxId = 0 +cdef dict g_pythonCallbacks = {} + +# TODO: send callbackId using CefBinaryNamedValue, see: +# http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10881 +cdef struct PythonCallback: + int callbackId + char uniqueCefBinaryValueSize[16] + +cdef CefRefPtr[CefBinaryValue] PutPythonCallback( + object browserId, + object frameId, + object function + ) except *: + global g_pythonCallbacks + global g_pythonCallbackMaxId + if not browserId: + raise Exception("PutPythonCallback() FAILED: browserId is empty") + if not frameId: + raise Exception("PutPythonCallback() FAILED: frameId is empty") + cdef PythonCallback pyCallback + g_pythonCallbackMaxId += 1 + pyCallback.callbackId = g_pythonCallbackMaxId + cdef CefRefPtr[CefBinaryValue] binaryValue = CefBinaryValue_Create( + &pyCallback, sizeof(pyCallback)) + # [0] browserId, [1] frameId, [2] function. + g_pythonCallbacks[g_pythonCallbackMaxId] = (browserId, frameId, function) + return binaryValue + +cdef public void RemovePythonCallbacksForFrame( + int frameId + ) except * with gil: + # Cannot remove elements from g_pythonCallbacks (dict) while iterating. + cdef list toRemove = [] + try: + global g_pythonCallbacks + for callbackId, value in g_pythonCallbacks.iteritems(): + if value[1] == frameId: + toRemove.append(callbackId) + for callbackId in toRemove: + del g_pythonCallbacks[callbackId] + Debug("RemovePythonCallbacksForFrame(): " \ + "removed python callback, callbackId = %s" \ + % callbackId) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef void RemovePythonCallbacksForBrowser( + int browserId) except *: + cdef list toRemove = [] + global g_pythonCallbacks + for callbackId, value in g_pythonCallbacks.iteritems(): + if value[0] == browserId: + toRemove.append(callbackId) + for callbackId in toRemove: + del g_pythonCallbacks[callbackId] + Debug("RemovePythonCallbacksForBrowser(): " \ + "removed python callback, callbackId = %s" \ + % callbackId) + +cdef public cpp_bool ExecutePythonCallback( + CefRefPtr[CefBrowser] cefBrowser, + int callbackId, + CefRefPtr[CefListValue] cefFunctionArguments, + ) except * with gil: + cdef object function + cdef list functionArguments + cdef object returnValue + try: + global g_pythonCallbacks + if callbackId in g_pythonCallbacks: + # [0] browserId, [1] frameId, [2] function. + function = g_pythonCallbacks[callbackId][2] + functionArguments = CefListValueToPyList( + cefBrowser, cefFunctionArguments) + returnValue = function(*functionArguments) + if returnValue != None: + Debug("ExecutePythonCallback() WARNING: function returned" \ + "value, but returning values to javascript is not " \ + "supported, function name = %s" % function.__name__) + return True + else: + Debug("ExecutePythonCallback() FAILED: callback not found, " \ + "callbackId = %s" % callbackId) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/render_handler_cef1.pyx b/cefpython/render_handler_cef1.pyx new file mode 100644 index 00000000..8fc37103 --- /dev/null +++ b/cefpython/render_handler_cef1.pyx @@ -0,0 +1,169 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# cef_paint_element_type_t, PaintElementType +PET_VIEW = cef_types.PET_VIEW +PET_POPUP = cef_types.PET_POPUP + +cdef public cpp_bool RenderHandler_GetViewRect( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetViewRect") + if callback: + ret = callback(pyBrowser, pyRect) + if ret: + assert (pyRect and len(pyRect) == 4), "rectangle not provided" + cefRect.x = pyRect[0] + cefRect.y = pyRect[1] + cefRect.width = pyRect[2] + cefRect.height = pyRect[3] + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetScreenRect( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetScreenRect") + if callback: + ret = callback(pyBrowser, pyRect) + if ret: + assert (pyRect and len(pyRect) == 4), ( + "rectangle not provided or invalid") + cefRect.x = pyRect[0] + cefRect.y = pyRect[1] + cefRect.width = pyRect[2] + cefRect.height = pyRect[3] + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetScreenPoint( + CefRefPtr[CefBrowser] cefBrowser, + int viewX, int viewY, + int& screenX, int& screenY + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list screenCoordinates = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetScreenPoint") + if callback: + ret = callback(pyBrowser, viewX, viewY, screenCoordinates) + if ret: + assert (screenCoordinates and len(screenCoordinates) == 2), ( + "screenCoordinates not provided or invalid") + (&screenX)[0] = int(screenCoordinates[0]) + (&screenY)[0] = int(screenCoordinates[1]) + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnPopupShow( + CefRefPtr[CefBrowser] cefBrowser, + cpp_bool show + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnPopupShow") + if callback: + callback(pyBrowser, show) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnPopupSize( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnPopupSize") + if callback: + pyRect = [cefRect.x, cefRect.y, cefRect.width, cefRect.height] + callback(pyBrowser, pyRect) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnPaint( + CefRefPtr[CefBrowser] cefBrowser, + cef_types.cef_paint_element_type_t paintElementType, + cpp_vector[CefRect]& cefDirtyRects, + void* cefBuffer + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyDirtyRects = [] + cdef list pyRect + cdef cpp_vector[CefRect].iterator iterator + cdef CefRect cefRect + cdef PaintBuffer paintBuffer + cdef int width + cdef int height + try: + pyBrowser = GetPyBrowser(cefBrowser) + + iterator = cefDirtyRects.begin() + while iterator != cefDirtyRects.end(): + cefRect = deref(iterator) + pyRect = [cefRect.x, cefRect.y, cefRect.width, cefRect.height] + pyDirtyRects.append(pyRect) + preinc(iterator) + + (width, height) = pyBrowser.GetSize(paintElementType) + paintBuffer = CreatePaintBuffer(cefBuffer, width, height) + + callback = pyBrowser.GetClientCallback("OnPaint") + if callback: + callback(pyBrowser, paintElementType, pyDirtyRects, paintBuffer) + else: + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnCursorChange( + CefRefPtr[CefBrowser] cefBrowser, + CefCursorHandle cursor + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnCursorChange") + if callback: + callback(pyBrowser, cursor) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/render_handler_cef3.pyx b/cefpython/render_handler_cef3.pyx new file mode 100644 index 00000000..7857030c --- /dev/null +++ b/cefpython/render_handler_cef3.pyx @@ -0,0 +1,222 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# cef_paint_element_type_t, PaintElementType +PET_VIEW = cef_types.PET_VIEW +PET_POPUP = cef_types.PET_POPUP + +cdef public cpp_bool RenderHandler_GetRootScreenRect( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetRootScreenRect") + if callback: + ret = callback(pyBrowser, pyRect) + if ret: + assert (pyRect and len(pyRect) == 4), "rectangle not provided" + cefRect.x = pyRect[0] + cefRect.y = pyRect[1] + cefRect.width = pyRect[2] + cefRect.height = pyRect[3] + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetViewRect( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetViewRect") + if callback: + ret = callback(pyBrowser, pyRect) + if ret: + assert (pyRect and len(pyRect) == 4), "rectangle not provided" + cefRect.x = pyRect[0] + cefRect.y = pyRect[1] + cefRect.width = pyRect[2] + cefRect.height = pyRect[3] + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetScreenRect( + CefRefPtr[CefBrowser] cefBrowser, + CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetScreenRect") + if callback: + ret = callback(pyBrowser, pyRect) + if ret: + assert (pyRect and len(pyRect) == 4), ( + "rectangle not provided or invalid") + cefRect.x = pyRect[0] + cefRect.y = pyRect[1] + cefRect.width = pyRect[2] + cefRect.height = pyRect[3] + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetScreenPoint( + CefRefPtr[CefBrowser] cefBrowser, + int viewX, int viewY, + int& screenX, int& screenY + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list screenCoordinates = [] + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("GetScreenPoint") + if callback: + ret = callback(pyBrowser, viewX, viewY, screenCoordinates) + if ret: + assert (screenCoordinates and len(screenCoordinates) == 2), ( + "screenCoordinates not provided or invalid") + (&screenX)[0] = int(screenCoordinates[0]) + (&screenY)[0] = int(screenCoordinates[1]) + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RenderHandler_GetScreenInfo( + CefRefPtr[CefBrowser] cefBrowser, + CefScreenInfo& cefScreenInfo + ) except * with gil: + # Not yet implemented. + return False + +cdef public void RenderHandler_OnPopupShow( + CefRefPtr[CefBrowser] cefBrowser, + cpp_bool show + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnPopupShow") + if callback: + callback(pyBrowser, show) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnPopupSize( + CefRefPtr[CefBrowser] cefBrowser, + const CefRect& cefRect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyRect + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnPopupSize") + if callback: + pyRect = [cefRect.x, cefRect.y, cefRect.width, cefRect.height] + callback(pyBrowser, pyRect) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnPaint( + CefRefPtr[CefBrowser] cefBrowser, + cef_types.cef_paint_element_type_t paintElementType, + cpp_vector[CefRect]& cefDirtyRects, + const void* cefBuffer, + int width, + int height + ) except * with gil: + cdef PyBrowser pyBrowser + cdef list pyDirtyRects = [] + cdef list pyRect + # TODO: cefDirtyRects should be const, but const_iterator is + # not yet implemented in libcpp.vector. + cdef cpp_vector[CefRect].iterator iterator + cdef CefRect cefRect + cdef PaintBuffer paintBuffer + try: + pyBrowser = GetPyBrowser(cefBrowser) + + iterator = cefDirtyRects.begin() + while iterator != cefDirtyRects.end(): + cefRect = deref(iterator) + pyRect = [cefRect.x, cefRect.y, cefRect.width, cefRect.height] + pyDirtyRects.append(pyRect) + preinc(iterator) + + # In CEF 1 width and height were fetched using GetSize(), + # but in CEF 3 they are passed as arguments to OnPaint(). + # OFF: | (width, height) = pyBrowser.GetSize(paintElementType) + + paintBuffer = CreatePaintBuffer(cefBuffer, width, height) + + callback = pyBrowser.GetClientCallback("OnPaint") + if callback: + callback(pyBrowser, paintElementType, pyDirtyRects, paintBuffer, + width, height) + else: + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnCursorChange( + CefRefPtr[CefBrowser] cefBrowser, + CefCursorHandle cursor + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnCursorChange") + if callback: + callback(pyBrowser, cursor) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RenderHandler_OnScrollOffsetChanged( + CefRefPtr[CefBrowser] cefBrowser + ) except * with gil: + cdef PyBrowser pyBrowser + try: + pyBrowser = GetPyBrowser(cefBrowser) + callback = pyBrowser.GetClientCallback("OnScrollOffsetChanged") + if callback: + callback(pyBrowser) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/request_cef1.pyx b/cefpython/request_cef1.pyx new file mode 100644 index 00000000..e06bcf2a --- /dev/null +++ b/cefpython/request_cef1.pyx @@ -0,0 +1,208 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class Request: + Flags = { + "None": cef_types.WUR_FLAG_NONE, + "SkipCache": cef_types.WUR_FLAG_SKIP_CACHE, + "AllowCachedCredentials": cef_types.WUR_FLAG_ALLOW_CACHED_CREDENTIALS, + "AllowCookies": cef_types.WUR_FLAG_ALLOW_COOKIES, + "ReportUploadProgress": cef_types.WUR_FLAG_REPORT_UPLOAD_PROGRESS, + "ReportLoadTiming": cef_types.WUR_FLAG_REPORT_LOAD_TIMING, + "ReportRawHeaders": cef_types.WUR_FLAG_REPORT_RAW_HEADERS, + } + + def __init__(self): + # Request object is just a public API wrapper, + # the real Request object is named PyRequest. + raise Exception("Request object cannot be instantiated directly, " + "use static method Request.CreateRequest()") + + @staticmethod + def CreateRequest(): + cdef CefRefPtr[CefRequest] cefRequest = CefRequest_Create() + cdef PyRequest pyRequest = CreatePyRequest(cefRequest) + return pyRequest + +cdef PyRequest CreatePyRequest(CefRefPtr[CefRequest] cefRequest): + # This can't be named "GetPyRequest()" as CefRequest has + # no unique identifier, so each time a different python object + # must be returned. + cdef PyRequest pyRequest = PyRequest() + pyRequest.cefRequest = cefRequest + return pyRequest + +cdef class PyRequest: + cdef CefRefPtr[CefRequest] cefRequest + + cdef CefRefPtr[CefRequest] GetCefRequest(self) except *: + if self.cefRequest != NULL and self.cefRequest.get(): + return self.cefRequest + raise Exception("PyRequest.GetCefRequest() failed: " + "CefRequest was destroyed") + + cpdef str GetUrl(self): + return CefToPyString(self.GetCefRequest().get().GetURL()) + + cpdef py_void SetUrl(self, py_string url): + cdef CefString cefUrl + PyToCefString(url, cefUrl) + self.GetCefRequest().get().SetURL(cefUrl) + + cpdef str GetMethod(self): + return CefToPyString(self.GetCefRequest().get().GetMethod()) + + cpdef py_void SetMethod(self, py_string method): + cdef CefString cefMethod + PyToCefString(method, cefMethod) + self.GetCefRequest().get().SetMethod(cefMethod) + + cpdef object GetPostData(self): + if self.GetMethod() != "POST": + return {} + cdef cpp_vector[CefRefPtr[CefPostDataElement]] elementVector + cdef CefRefPtr[CefPostData] postData = ( + self.GetCefRequest().get().GetPostData()) + if postData.get().GetElementCount() == 0: + return {} + postData.get().GetElements(elementVector) + cdef cpp_vector[CefRefPtr[CefPostDataElement]].iterator iterator = ( + elementVector.begin()) + cdef CefRefPtr[CefPostDataElement] postDataElement + cdef list retMultipart = [] + cdef dict retUrlEncoded = {} + # pyData is really of type "str", but Cython will throw + # an error if we use that type: "Cannot convert 'bytes' + # object to str implicitly. This is not portable to Py3." + cdef object pyData + cdef size_t bytesCount + cdef void* voidData + cdef str pyFile + while iterator != elementVector.end(): + postDataElement = deref(iterator) + if postDataElement.get().GetType() == cef_types.PDE_TYPE_EMPTY: + # May return an empty dict - retUrlEncoded. + pass + elif postDataElement.get().GetType() == cef_types.PDE_TYPE_BYTES: + bytesCount = postDataElement.get().GetBytesCount() + voidData = malloc(bytesCount) + postDataElement.get().GetBytes(bytesCount, voidData) + pyData = VoidPtrToString(voidData, bytesCount) + free(voidData) + if (pyData.startswith('--') or retMultipart): + # Content-Type: multipart/form-data + retMultipart.append(pyData) + else: + # Content-Type: application/x-www-form-urlencoded + retUrlEncoded.update(urlparse.parse_qsl(qs=pyData, + keep_blank_values=True)) + elif postDataElement.get().GetType() == cef_types.PDE_TYPE_FILE: + pyFile = CefToPyString(postDataElement.get().GetFile()) + retMultipart.append("@"+pyFile) + else: + raise Exception("Invalid type of CefPostDataElement") + preinc(iterator) + if retMultipart: + return retMultipart + else: + return retUrlEncoded + + cpdef py_void SetPostData(self, object pyPostData): + cdef CefRefPtr[CefPostData] postData = ( + self.GetCefRequest().get().GetPostData()) + postData.get().RemoveElements() + cdef CefRefPtr[CefPostDataElement] postDataElement + cdef py_string pyElement + cdef CefString sfile + if type(pyPostData) == list: + for pyElement in pyPostData: + if pyElement.startswith('--'): + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToBytes(len(pyElement), + pyElement) + elif pyElement.startswith('@'): + postDataElement = CefPostDataElement_Create() + PyToCefString(pyElement[1:], sfile) + postDataElement.get().SetToFile(sfile) + elif not pyElement: + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToEmpty() + else: + raise Exception("Invalid element in postData: %s" % ( + pyElement)) + postData.get().AddElement(postDataElement) + elif type(pyPostData) == dict: + pyElement = urllib.urlencode(pyPostData) + pyElement = str(pyElement) + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToBytes(len(pyElement), pyElement) + postData.get().AddElement(postDataElement) + else: + raise Exception("Invalid type of postData, only dict|list allowed") + + cpdef dict GetHeaderMap(self): + cdef list headerMultimap = self.GetHeaderMultimap() + cdef dict headerMap = {} + cdef tuple headerTuple + for headerTuple in headerMultimap: + key = headerTuple[0] + value = headerTuple[1] + headerMap[key] = value + return headerMap + + cpdef list GetHeaderMultimap(self): + cdef cpp_multimap[CefString, CefString] cefHeaderMap + self.GetCefRequest().get().GetHeaderMap(cefHeaderMap) + cdef list pyHeaderMultimap = [] + cdef cpp_multimap[CefString, CefString].iterator iterator = ( + cefHeaderMap.begin()) + cdef CefString cefKey + cdef CefString cefValue + cdef str pyKey + cdef str pyValue + while iterator != cefHeaderMap.end(): + cefKey = deref(iterator).first + cefValue = deref(iterator).second + pyKey = CefToPyString(cefKey) + pyValue = CefToPyString(cefValue) + pyHeaderMultimap.append((pyKey, pyValue)) + preinc(iterator) + return pyHeaderMultimap + + cpdef py_void SetHeaderMap(self, dict headerMap): + assert len(headerMap) > 0, "headerMap param is empty" + cpdef list headerMultimap = [] + cdef object key + for key in headerMap: + headerMultimap.append((str(key), str(headerMap[key]))) + self.SetHeaderMultimap(headerMultimap) + + cpdef py_void SetHeaderMultimap(self, list headerMultimap): + assert len(headerMultimap) > 0, "headerMultimap param is empty" + cdef cpp_multimap[CefString, CefString] cefHeaderMap + cdef CefString cefKey + cdef CefString cefValue + cdef cpp_pair[CefString, CefString] pair + cdef tuple headerTuple + for headerTuple in headerMultimap: + PyToCefString(str(headerTuple[0]), cefKey) + PyToCefString(str(headerTuple[1]), cefValue) + pair.first, pair.second = cefKey, cefValue + cefHeaderMap.insert(pair) + self.GetCefRequest().get().SetHeaderMap(cefHeaderMap) + + cpdef int GetFlags(self) except *: + return self.GetCefRequest().get().GetFlags() + + cpdef py_void SetFlags(self, int flags): + self.GetCefRequest().get().SetFlags( + flags) + + cpdef str GetFirstPartyForCookies(self): + return CefToPyString( + self.GetCefRequest().get().GetFirstPartyForCookies()) + + cpdef py_void SetFirstPartyForCookies(self, py_string url): + self.GetCefRequest().get().SetFirstPartyForCookies( + PyToCefStringValue(url)) diff --git a/cefpython/request_cef3.pyx b/cefpython/request_cef3.pyx new file mode 100644 index 00000000..99f5cf03 --- /dev/null +++ b/cefpython/request_cef3.pyx @@ -0,0 +1,209 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class Request: + Flags = { + "None": cef_types.UR_FLAG_NONE, + "SkipCache": cef_types.UR_FLAG_SKIP_CACHE, + "AllowCachedCredentials": cef_types.UR_FLAG_ALLOW_CACHED_CREDENTIALS, + "AllowCookies": cef_types.UR_FLAG_ALLOW_COOKIES, + "ReportUploadProgress": cef_types.UR_FLAG_REPORT_UPLOAD_PROGRESS, + "ReportLoadTiming": cef_types.UR_FLAG_REPORT_LOAD_TIMING, + "ReportRawHeaders": cef_types.UR_FLAG_REPORT_RAW_HEADERS, + "NoDownloadData": cef_types.UR_FLAG_NO_DOWNLOAD_DATA, + "NoRetryOn5xx": cef_types.UR_FLAG_NO_RETRY_ON_5XX, + } + + def __init__(self): + # Request object is just a public API wrapper, + # the real Request object is named PyRequest. + raise Exception("Request object cannot be instantiated directly, " + "use static method Request.CreateRequest()") + + @staticmethod + def CreateRequest(): + cdef CefRefPtr[CefRequest] cefRequest = CefRequest_Create() + cdef PyRequest pyRequest = CreatePyRequest(cefRequest) + return pyRequest + +cdef PyRequest CreatePyRequest(CefRefPtr[CefRequest] cefRequest): + # This can't be named "GetPyRequest()" as CefRequest has + # no unique identifier, so each time a different python object + # must be returned. + cdef PyRequest pyRequest = PyRequest() + pyRequest.cefRequest = cefRequest + return pyRequest + +cdef class PyRequest: + cdef CefRefPtr[CefRequest] cefRequest + + cdef CefRefPtr[CefRequest] GetCefRequest(self) except *: + if self.cefRequest != NULL and self.cefRequest.get(): + return self.cefRequest + raise Exception("PyRequest.GetCefRequest() failed: " + "CefRequest was destroyed") + + cpdef str GetUrl(self): + return CefToPyString(self.GetCefRequest().get().GetURL()) + + cpdef py_void SetUrl(self, py_string url): + cdef CefString cefUrl + PyToCefString(url, cefUrl) + self.GetCefRequest().get().SetURL(cefUrl) + + cpdef str GetMethod(self): + return CefToPyString(self.GetCefRequest().get().GetMethod()) + + cpdef py_void SetMethod(self, py_string method): + cdef CefString cefMethod + PyToCefString(method, cefMethod) + self.GetCefRequest().get().SetMethod(cefMethod) + + cpdef object GetPostData(self): + if self.GetMethod() != "POST": + return {} + cdef cpp_vector[CefRefPtr[CefPostDataElement]] elementVector + cdef CefRefPtr[CefPostData] postData = ( + self.GetCefRequest().get().GetPostData()) + if postData.get().GetElementCount() == 0: + return {} + postData.get().GetElements(elementVector) + cdef cpp_vector[CefRefPtr[CefPostDataElement]].iterator iterator = ( + elementVector.begin()) + cdef CefRefPtr[CefPostDataElement] postDataElement + cdef list retMultipart = [] + cdef dict retUrlEncoded = {} + # pyData is really of type "str", but Cython will throw + # an error if we use that type: "Cannot convert 'bytes' + # object to str implicitly. This is not portable to Py3." + cdef object pyData + cdef size_t bytesCount + cdef void* voidData + cdef str pyFile + while iterator != elementVector.end(): + postDataElement = deref(iterator) + if postDataElement.get().GetType() == cef_types.PDE_TYPE_EMPTY: + # May return an empty dict - retUrlEncoded. + pass + elif postDataElement.get().GetType() == cef_types.PDE_TYPE_BYTES: + bytesCount = postDataElement.get().GetBytesCount() + voidData = malloc(bytesCount) + postDataElement.get().GetBytes(bytesCount, voidData) + pyData = VoidPtrToString(voidData, bytesCount) + free(voidData) + if (pyData.startswith('--') or retMultipart): + # Content-Type: multipart/form-data + retMultipart.append(pyData) + else: + # Content-Type: application/x-www-form-urlencoded + retUrlEncoded.update(urlparse.parse_qsl(qs=pyData, + keep_blank_values=True)) + elif postDataElement.get().GetType() == cef_types.PDE_TYPE_FILE: + pyFile = CefToPyString(postDataElement.get().GetFile()) + retMultipart.append("@"+pyFile) + else: + raise Exception("Invalid type of CefPostDataElement") + preinc(iterator) + if retMultipart: + return retMultipart + else: + return retUrlEncoded + + cpdef py_void SetPostData(self, object pyPostData): + cdef CefRefPtr[CefPostData] postData = ( + self.GetCefRequest().get().GetPostData()) + postData.get().RemoveElements() + cdef CefRefPtr[CefPostDataElement] postDataElement + cdef py_string pyElement + cdef CefString sfile + if type(pyPostData) == list: + for pyElement in pyPostData: + if pyElement.startswith('--'): + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToBytes(len(pyElement), + pyElement) + elif pyElement.startswith('@'): + postDataElement = CefPostDataElement_Create() + PyToCefString(pyElement[1:], sfile) + postDataElement.get().SetToFile(sfile) + elif not pyElement: + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToEmpty() + else: + raise Exception("Invalid element in postData: %s" % ( + pyElement)) + postData.get().AddElement(postDataElement) + elif type(pyPostData) == dict: + pyElement = urllib.urlencode(pyPostData) + pyElement = str(pyElement) + postDataElement = CefPostDataElement_Create() + postDataElement.get().SetToBytes(len(pyElement), pyElement) + postData.get().AddElement(postDataElement) + else: + raise Exception("Invalid type of postData, only dict|list allowed") + + cpdef dict GetHeaderMap(self): + cdef list headerMultimap = self.GetHeaderMultimap() + cdef dict headerMap = {} + cdef tuple headerTuple + for headerTuple in headerMultimap: + key = headerTuple[0] + value = headerTuple[1] + headerMap[key] = value + return headerMap + + cpdef list GetHeaderMultimap(self): + cdef cpp_multimap[CefString, CefString] cefHeaderMap + self.GetCefRequest().get().GetHeaderMap(cefHeaderMap) + cdef list pyHeaderMultimap = [] + cdef cpp_multimap[CefString, CefString].iterator iterator = ( + cefHeaderMap.begin()) + cdef CefString cefKey + cdef CefString cefValue + cdef str pyKey + cdef str pyValue + while iterator != cefHeaderMap.end(): + cefKey = deref(iterator).first + cefValue = deref(iterator).second + pyKey = CefToPyString(cefKey) + pyValue = CefToPyString(cefValue) + pyHeaderMultimap.append((pyKey, pyValue)) + preinc(iterator) + return pyHeaderMultimap + + cpdef py_void SetHeaderMap(self, dict headerMap): + assert len(headerMap) > 0, "headerMap param is empty" + cpdef list headerMultimap = [] + cdef object key + for key in headerMap: + headerMultimap.append((str(key), str(headerMap[key]))) + self.SetHeaderMultimap(headerMultimap) + + cpdef py_void SetHeaderMultimap(self, list headerMultimap): + assert len(headerMultimap) > 0, "headerMultimap param is empty" + cdef cpp_multimap[CefString, CefString] cefHeaderMap + cdef CefString cefKey + cdef CefString cefValue + cdef cpp_pair[CefString, CefString] pair + cdef tuple headerTuple + for headerTuple in headerMultimap: + PyToCefString(str(headerTuple[0]), cefKey) + PyToCefString(str(headerTuple[1]), cefValue) + pair.first, pair.second = cefKey, cefValue + cefHeaderMap.insert(pair) + self.GetCefRequest().get().SetHeaderMap(cefHeaderMap) + + cpdef int GetFlags(self) except *: + return self.GetCefRequest().get().GetFlags() + + cpdef py_void SetFlags(self, int flags): + self.GetCefRequest().get().SetFlags(flags) + + cpdef str GetFirstPartyForCookies(self): + return CefToPyString( + self.GetCefRequest().get().GetFirstPartyForCookies()) + + cpdef py_void SetFirstPartyForCookies(self, py_string url): + self.GetCefRequest().get().SetFirstPartyForCookies( + PyToCefStringValue(url)) diff --git a/cefpython/request_handler_cef1.pyx b/cefpython/request_handler_cef1.pyx new file mode 100644 index 00000000..0415cc3a --- /dev/null +++ b/cefpython/request_handler_cef1.pyx @@ -0,0 +1,271 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +NAVTYPE_LINKCLICKED = cef_types.NAVTYPE_LINKCLICKED +NAVTYPE_FORMSUBMITTED = cef_types.NAVTYPE_FORMSUBMITTED +NAVTYPE_BACKFORWARD = cef_types.NAVTYPE_BACKFORWARD +NAVTYPE_RELOAD = cef_types.NAVTYPE_RELOAD +NAVTYPE_FORMRESUBMITTED = cef_types.NAVTYPE_FORMRESUBMITTED +NAVTYPE_OTHER = cef_types.NAVTYPE_OTHER +NAVTYPE_LINKDROPPED = cef_types.NAVTYPE_LINKDROPPED + +cdef public cpp_bool RequestHandler_OnBeforeBrowse( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefRequest] cefRequest, + cef_types.cef_handler_navtype_t navType, + cpp_bool isRedirect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef PyRequest pyRequest + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyRequest = CreatePyRequest(cefRequest) + callback = pyBrowser.GetClientCallback("OnBeforeBrowse") + if callback: + return bool(callback( + pyBrowser, pyFrame, pyRequest, navType, isRedirect)) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnBeforeResourceLoad( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefRequest] cefRequest, + CefString& cefRedirectUrl, + CefRefPtr[CefStreamReader]& cefStreamReader, + CefRefPtr[CefResponse] cefResponse, + int loadFlags + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyRequest pyRequest + cdef list pyRedirectUrl + cdef PyStreamReader pyStreamReader + cdef PyResponse pyResponse + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyRequest = CreatePyRequest(cefRequest) + pyRedirectUrl = [""] + pyStreamReader = PyStreamReader() + pyResponse = CreatePyResponse(cefResponse) + callback = pyBrowser.GetClientCallback("OnBeforeResourceLoad") + if callback: + ret = callback(pyBrowser, pyRequest, pyRedirectUrl, + pyStreamReader, pyResponse, loadFlags) + assert type(pyRedirectUrl) == list + assert type(pyRedirectUrl[0]) == str + if pyRedirectUrl[0]: + PyToCefString(pyRedirectUrl[0], cefRedirectUrl) + if pyStreamReader.HasCefStreamReader(): + cefStreamReader.swap(pyStreamReader.GetCefStreamReader()) + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnResourceRedirect( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefOldUrl, + CefString& cefNewUrl + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyOldUrl + cdef list pyNewUrl # = [""] pass by reference (out). + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyOldUrl = CefToPyString(cefOldUrl) + pyNewUrl = [CefToPyString(cefNewUrl)] + callback = pyBrowser.GetClientCallback("OnResourceRedirect") + if callback: + callback(pyBrowser, pyOldUrl, pyNewUrl) + if pyNewUrl[0]: + PyToCefString(pyNewUrl[0], cefNewUrl) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnResourceResponse( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefUrl, + CefRefPtr[CefResponse] cefResponse, + CefRefPtr[CefContentFilter]& cefContentFilter + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyUrl + cdef PyResponse pyResponse + cdef PyContentFilter pyContentFilter + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyUrl = CefToPyString(cefUrl) + pyResponse = CreatePyResponse(cefResponse) + pyContentFilter = PyContentFilter() + callback = pyBrowser.GetClientCallback("OnResourceResponse") + if callback: + callback(pyBrowser, pyUrl, pyResponse, pyContentFilter) + if pyContentFilter.HasHandler(): + cefContentFilter.swap(pyContentFilter.GetCefContentFilter()) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnProtocolExecution( + CefRefPtr[CefBrowser] cefBrowser, + CefString& cefUrl, + cpp_bool& cefAllowOSExecution + ) except * with gil: + # TODO: needs testing. + cdef PyBrowser pyBrowser + cdef str pyUrl + cdef list pyAllowOSExecution # = [True] pass by reference (out). + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyUrl = CefToPyString(cefUrl) + pyAllowOSExecution = [bool(cefAllowOSExecution)] + callback = pyBrowser.GetClientCallback("OnProtocolExecution") + if callback: + ret = callback( + pyBrowser, pyUrl, pyAllowOSExecution) + # Since Cython 0.17.4 assigning a value to an argument + # passed by reference will throw an error, the fix is to + # to use "(&arg)[0] =" instead of "arg =", see this topic: + # https://groups.google.com/forum/#!msg/cython-users/j58Sp3QMrD4/y9vJy9YBi_kJ + # For CefRefPtr you should use swap() method instead. + (&cefAllowOSExecution)[0] = bool(pyAllowOSExecution[0]) + return bool(ret) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_GetDownloadHandler( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefMimeType, + const CefString& cefFilename, + cef_types.int64 cefContentLength, + CefRefPtr[CefDownloadHandler]& cefDownloadHandler + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyMimeType + cdef str pyFilename + cdef long pyContentLength + cdef object callback + cdef object userDownloadHandler + cdef CefRefPtr[CefDownloadHandler] downloadHandler + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyMimeType = CefToPyString(cefMimeType) + pyFilename = CefToPyString(cefFilename) + pyContentLength = cefContentLength + callback = pyBrowser.GetClientCallback("GetDownloadHandler") + if callback: + userDownloadHandler = callback(pyBrowser, pyMimeType, pyFilename, + pyContentLength) + if userDownloadHandler: + downloadHandler = StoreUserDownloadHandler(userDownloadHandler) + cefDownloadHandler.swap(downloadHandler) + return True + else: + return False + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_GetAuthCredentials( + CefRefPtr[CefBrowser] cefBrowser, + cpp_bool cefIsProxy, + CefString& cefHost, + int cefPort, + CefString& cefRealm, + CefString& cefScheme, + CefString& cefUsername, + CefString& cefPassword + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_bool pyIsProxy + cdef str pyHost + cdef int pyPort + cdef str pyRealm + cdef str pyScheme + cdef list pyUsername # = [""] pass by reference (out). + cdef list pyPassword + cdef object callback + cdef py_bool ret + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyIsProxy = bool(cefIsProxy) + pyHost = CefToPyString(cefHost) + pyPort = int(cefPort) + pyRealm = CefToPyString(cefRealm) + pyScheme = CefToPyString(cefScheme) + pyUsername = [""] + pyPassword = [""] + callback = pyBrowser.GetClientCallback("GetAuthCredentials") + if callback: + ret = callback( + pyBrowser, + pyIsProxy, pyHost, pyPort, pyRealm, pyScheme, + pyUsername, pyPassword) + if ret: + PyToCefString(pyUsername[0], cefUsername) + PyToCefString(pyPassword[0], cefPassword) + return bool(ret) + else: + # Default implementation. + IF UNAME_SYSNAME == "Windows": + ret = HttpAuthenticationDialog( + pyBrowser, + pyIsProxy, pyHost, pyPort, pyRealm, pyScheme, + pyUsername, pyPassword) + if ret: + PyToCefString(pyUsername[0], cefUsername) + PyToCefString(pyPassword[0], cefPassword) + return bool(ret) + ELSE: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public CefRefPtr[CefCookieManager] RequestHandler_GetCookieManager( + CefRefPtr[CefBrowser] cefBrowser, + CefString& mainUrl + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyMainUrl + cdef object callback + cdef PyCookieManager ret + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyBrowser = GetPyBrowser(cefBrowser) + pyMainUrl = CefToPyString(mainUrl) + callback = pyBrowser.GetClientCallback("GetCookieManager") + if callback: + ret = callback(pyBrowser, pyMainUrl) + if ret: + if isinstance(ret, PyCookieManager): + return ret.cefCookieManager + else: + raise Exception("Expected CookieManager object") + return NULL + else: + return NULL + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/request_handler_cef3.pyx b/cefpython/request_handler_cef3.pyx new file mode 100644 index 00000000..2987418f --- /dev/null +++ b/cefpython/request_handler_cef3.pyx @@ -0,0 +1,398 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# cef_termination_status_t +TS_ABNORMAL_TERMINATION = cef_types.TS_ABNORMAL_TERMINATION +TS_PROCESS_WAS_KILLED = cef_types.TS_PROCESS_WAS_KILLED +TS_PROCESS_CRASHED = cef_types.TS_PROCESS_CRASHED + +# ----------------------------------------------------------------------------- +# PyAuthCallback +# ----------------------------------------------------------------------------- +cdef PyAuthCallback CreatePyAuthCallback( + CefRefPtr[CefAuthCallback] cefCallback): + cdef PyAuthCallback pyCallback = PyAuthCallback() + pyCallback.cefCallback = cefCallback + return pyCallback + +cdef class PyAuthCallback: + cdef CefRefPtr[CefAuthCallback] cefCallback + + cpdef py_void Continue(self, py_string username, py_string password): + self.cefCallback.get().Continue( + PyToCefStringValue(username), + PyToCefStringValue(password)) + + cpdef py_void Cancel(self): + self.cefCallback.get().Cancel() + +# ----------------------------------------------------------------------------- +# PyQuotaCallback +# ----------------------------------------------------------------------------- +cdef PyQuotaCallback CreatePyQuotaCallback( + CefRefPtr[CefQuotaCallback] cefCallback): + cdef PyQuotaCallback pyCallback = PyQuotaCallback() + pyCallback.cefCallback = cefCallback + return pyCallback + +cdef class PyQuotaCallback: + cdef CefRefPtr[CefQuotaCallback] cefCallback + + cpdef py_void Continue(self, py_bool allow): + self.cefCallback.get().Continue(bool(allow)) + + cpdef py_void Cancel(self): + self.cefCallback.get().Cancel() + +# ----------------------------------------------------------------------------- +# PyAllowCertificateErrorCallback +# ----------------------------------------------------------------------------- +cdef PyAllowCertificateErrorCallback CreatePyAllowCertificateErrorCallback( + CefRefPtr[CefAllowCertificateErrorCallback] cefCallback): + cdef PyAllowCertificateErrorCallback pyCallback = \ + PyAllowCertificateErrorCallback() + pyCallback.cefCallback = cefCallback + return pyCallback + +cdef class PyAllowCertificateErrorCallback: + cdef CefRefPtr[CefAllowCertificateErrorCallback] cefCallback + + cpdef py_void Continue(self, py_bool allow): + self.cefCallback.get().Continue(bool(allow)) + +# ----------------------------------------------------------------------------- +# RequestHandler +# ----------------------------------------------------------------------------- + +cdef public cpp_bool RequestHandler_OnBeforeResourceLoad( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefRequest] cefRequest + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef PyRequest pyRequest + cdef object clientCallback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyRequest = CreatePyRequest(cefRequest) + clientCallback = pyBrowser.GetClientCallback("OnBeforeResourceLoad") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyFrame, pyRequest) + return bool(returnValue) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnBeforeBrowse( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefRequest] cefRequest, + cpp_bool cefIsRedirect + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef PyRequest pyRequest + cdef py_bool pyIsRedirect + cdef object clientCallback + cdef py_bool returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyRequest = CreatePyRequest(cefRequest) + pyIsRedirect = bool(cefIsRedirect) + clientCallback = pyBrowser.GetClientCallback("OnBeforeBrowse") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyFrame, pyRequest, + pyIsRedirect) + return bool(returnValue) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public CefRefPtr[CefResourceHandler] RequestHandler_GetResourceHandler( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefRequest] cefRequest + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef PyRequest pyRequest + cdef object clientCallback + cdef object returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyRequest = CreatePyRequest(cefRequest) + clientCallback = pyBrowser.GetClientCallback("GetResourceHandler") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyFrame, pyRequest) + if returnValue: + return CreateResourceHandler(returnValue) + else: + return NULL + else: + return NULL + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnResourceRedirect( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + const CefString& cefOldUrl, + CefString& cefNewUrl + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef str pyOldUrl + cdef list pyNewUrlOut + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyOldUrl = CefToPyString(cefOldUrl) + pyNewUrlOut = [CefToPyString(cefNewUrl)] + clientCallback = pyBrowser.GetClientCallback("OnResourceRedirect") + if clientCallback: + clientCallback(pyBrowser, pyFrame, pyOldUrl, pyNewUrlOut) + if pyNewUrlOut[0]: + PyToCefString(pyNewUrlOut[0], cefNewUrl) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_GetAuthCredentials( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + cpp_bool cefIsProxy, + const CefString& cefHost, + int cefPort, + const CefString& cefRealm, + const CefString& cefScheme, + CefRefPtr[CefAuthCallback] cefAuthCallback + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef py_bool pyIsProxy + cdef str pyHost + cdef int pyPort + cdef str pyRealm + cdef str pyScheme + cdef PyAuthCallback pyAuthCallback + cdef py_bool returnValue + cdef list pyUsernameOut + cdef list pyPasswordOut + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + pyIsProxy = bool(cefIsProxy) + pyHost = CefToPyString(cefHost) + pyPort = int(cefPort) + pyRealm = CefToPyString(cefRealm) + pyScheme = CefToPyString(cefScheme) + pyAuthCallback = CreatePyAuthCallback(cefAuthCallback) + pyUsernameOut = [""] + pyPasswordOut = [""] + clientCallback = pyBrowser.GetClientCallback("GetAuthCredentials") + if clientCallback: + returnValue = clientCallback( + pyBrowser, pyFrame, + pyIsProxy, pyHost, pyPort, pyRealm, pyScheme, + pyAuthCallback) + return bool(returnValue) + else: + # TODO: port it from CEF 1, copy the cef1/http_authentication/. + # -- + # Default implementation for Windows. + # IF UNAME_SYSNAME == "Windows": + # returnValue = HttpAuthenticationDialog( + # pyBrowser, + # pyIsProxy, pyHost, pyPort, pyRealm, pyScheme, + # pyUsernameOut, pyPasswordOut) + # if returnValue: + # pyAuthCallback.Continue(pyUsernameOut[0], pyPasswordOut[0]) + # return True + # return False + # ELSE: + # return False + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnQuotaRequest( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefOriginUrl, + int64 newSize, + CefRefPtr[CefQuotaCallback] cefQuotaCallback + ) except * with gil: + cdef PyBrowser pyBrowser + cdef py_string pyOriginUrl + cdef py_bool returnValue + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyOriginUrl = CefToPyString(cefOriginUrl) + clientCallback = pyBrowser.GetClientCallback("OnQuotaRequest") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyOriginUrl, long(newSize), + CreatePyQuotaCallback(cefQuotaCallback)) + return bool(returnValue) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public CefRefPtr[CefCookieManager] RequestHandler_GetCookieManager( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefMainUrl + ) except * with gil: + # In CEF the GetCookieManager callback belongs to + # CefRequestContextHandler. + # In an exceptional case the browser parameter may be None + # due to limitation in CEF API. No workaround as of now. + cdef PyBrowser pyBrowser + cdef str pyMainUrl + cdef object clientCallback + cdef PyCookieManager returnValue + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyMainUrl = CefToPyString(cefMainUrl) + if pyBrowser: + # Browser may be empty. + clientCallback = pyBrowser.GetClientCallback("GetCookieManager") + if clientCallback: + returnValue = clientCallback(pyBrowser, pyMainUrl) + if returnValue: + if isinstance(returnValue, PyCookieManager): + return returnValue.cefCookieManager + else: + raise Exception("Expected a CookieManager object") + return NULL + else: + return NULL + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnProtocolExecution( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefUrl, + cpp_bool& cefAllowOSExecution + ) except * with gil: + cdef PyBrowser pyBrowser + cdef str pyUrl + cdef list pyAllowOSExecutionOut + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyUrl = CefToPyString(cefUrl) + pyAllowOSExecutionOut = [bool(cefAllowOSExecution)] + clientCallback = pyBrowser.GetClientCallback("OnProtocolExecution") + if clientCallback: + clientCallback(pyBrowser, pyUrl, pyAllowOSExecutionOut) + # Since Cython 0.17.4 assigning a value to an argument + # passed by reference will throw an error, the fix is to + # to use "(&arg)[0] =" instead of "arg =", see this topic: + # https://groups.google.com/forum/#!msg/cython-users/j58Sp3QMrD4/y9vJy9YBi_kJ + # For CefRefPtr you should use swap() method instead. + (&cefAllowOSExecution)[0] = 1 + #(&cefAllowOSExecution)[0] = bool(pyAllowOSExecutionOut[0]) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnBeforePluginLoad( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefUrl, + const CefString& cefPolicyUrl, + CefRefPtr[CefWebPluginInfo] cefInfo + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyWebPluginInfo pyInfo + cdef py_bool returnValue + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyInfo = CreatePyWebPluginInfo(cefInfo) + clientCallback = GetGlobalClientCallback("OnBeforePluginLoad") + if clientCallback: + returnValue = clientCallback(pyBrowser, CefToPyString(cefUrl), + CefToPyString(cefPolicyUrl), pyInfo) + return bool(returnValue) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool RequestHandler_OnCertificateError( + int certError, + const CefString& cefRequestUrl, + CefRefPtr[CefAllowCertificateErrorCallback] cefCertCallback + ) except * with gil: + cdef py_bool returnValue + cdef object clientCallback + try: + clientCallback = GetGlobalClientCallback("OnCertificateError") + if clientCallback: + returnValue = clientCallback(certError, + CefToPyString(cefRequestUrl), + CreatePyAllowCertificateErrorCallback(cefCertCallback)) + return bool(returnValue) + else: + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnRendererProcessTerminated( + CefRefPtr[CefBrowser] cefBrowser, + cef_types.cef_termination_status_t cefStatus + ) except * with gil: + # TODO: proccess may crash during browser creation. Let this callback + # to be set either through cefpython.SetGlobalClientCallback() + # or PyBrowser.SetClientCallback(). Modify the + # PyBrowser.GetClientCallback() implementation to return a global + # callback first if set. + cdef PyBrowser pyBrowser + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + clientCallback = pyBrowser.GetClientCallback( + "OnRendererProcessTerminated") + if clientCallback: + clientCallback(pyBrowser, cefStatus) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void RequestHandler_OnPluginCrashed( + CefRefPtr[CefBrowser] cefBrowser, + const CefString& cefPluginPath + ) except * with gil: + # TODO: plugin may crash during browser creation. Let this callback + # to be set either through cefpython.SetGlobalClientCallback() + # or PyBrowser.SetClientCallback(). Modify the + # PyBrowser.GetClientCallback() implementation to return a global + # callback first if set. + cdef PyBrowser pyBrowser + cdef object clientCallback + try: + pyBrowser = GetPyBrowser(cefBrowser) + clientCallback = pyBrowser.GetClientCallback("OnPluginCrashed") + if clientCallback: + clientCallback(pyBrowser, CefToPyString(cefPluginPath)) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/resource_handler_cef3.pyx b/cefpython/resource_handler_cef3.pyx new file mode 100644 index 00000000..ef3911c0 --- /dev/null +++ b/cefpython/resource_handler_cef3.pyx @@ -0,0 +1,236 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# ----------------------------------------------------------------------------- +# Globals +# ----------------------------------------------------------------------------- + +# See StoreUserCookieVisitor(). +cdef object g_userResourceHandler = weakref.WeakValueDictionary() +cdef int g_userResourceHandlerMaxId = 0 + + +# ----------------------------------------------------------------------------- +# ResourceHandler +# ----------------------------------------------------------------------------- + +cdef py_void ValidateUserResourceHandler(object userResourceHandler): + cdef list methods = ["ProcessRequest", "GetResponseHeaders", + "ReadResponse", "CanGetCookie", "CanSetCookie", "Cancel"] + for method in methods: + if userResourceHandler and hasattr(userResourceHandler, method) \ + and callable(getattr(userResourceHandler, method)): + # Okay. + continue + else: + raise Exception("ResourceHandler object is missing method: %s" \ + % method) + +cdef CefRefPtr[CefResourceHandler] CreateResourceHandler( + object userResourceHandler) except *: + ValidateUserResourceHandler(userResourceHandler) + cdef int resourceHandlerId = StoreUserResourceHandler(userResourceHandler) + cdef CefRefPtr[CefResourceHandler] resourceHandler = \ + new ResourceHandler( \ + resourceHandlerId) + return resourceHandler + +cdef int StoreUserResourceHandler(object userResourceHandler) except *: + global g_userResourceHandlerMaxId + global g_userResourceHandler + g_userResourceHandlerMaxId += 1 + g_userResourceHandler[g_userResourceHandlerMaxId] = userResourceHandler + return g_userResourceHandlerMaxId + +cdef PyResourceHandler GetPyResourceHandler(int resourceHandlerId): + global g_userResourceHandler + cdef object userResourceHandler + cdef PyResourceHandler pyResourceHandler + if resourceHandlerId in g_userResourceHandler: + userResourceHandler = g_userResourceHandler[resourceHandlerId] + pyResourceHandler = PyResourceHandler(userResourceHandler) + return pyResourceHandler + +cdef class PyResourceHandler: + cdef object userResourceHandler + + def __init__(self, object userResourceHandler): + self.userResourceHandler = userResourceHandler + + cdef object GetCallback(self, str funcName): + if self.userResourceHandler and ( + hasattr(self.userResourceHandler, funcName) and ( + callable(getattr(self.userResourceHandler, funcName)))): + return getattr(self.userResourceHandler, funcName) + +# ------------------------------------------------------------------------------ +# ResourceHandler callbacks +# ------------------------------------------------------------------------------ + +cdef public cpp_bool ResourceHandler_ProcessRequest( + int resourceHandlerId, + CefRefPtr[CefRequest] cefRequest, + CefRefPtr[CefCallback] cefCallback + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + cdef py_bool returnValue + cdef PyRequest pyRequest + cdef PyCallback pyCallback + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + pyRequest = CreatePyRequest(cefRequest) + pyCallback = CreatePyCallback(cefCallback) + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("ProcessRequest") + if userCallback: + returnValue = userCallback(pyRequest, pyCallback) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void ResourceHandler_GetResponseHeaders( + int resourceHandlerId, + CefRefPtr[CefResponse] cefResponse, + int64& cefResponseLength, + CefString& cefRedirectUrl + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + cdef py_bool returnValue + cdef PyResponse pyResponse + cdef list responseLengthOut + cdef list redirectUrlOut + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + pyResponse = CreatePyResponse(cefResponse) + responseLengthOut = [cefResponseLength] + redirectUrlOut = [CefToPyString(cefRedirectUrl)] + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("GetResponseHeaders") + if userCallback: + returnValue = userCallback(pyResponse, responseLengthOut, + redirectUrlOut) + (&cefResponseLength)[0] = long(responseLengthOut[0]) + if (redirectUrlOut[0]): + PyToCefString(redirectUrlOut[0], cefRedirectUrl) + return + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool ResourceHandler_ReadResponse( + int resourceHandlerId, + void* cefDataOut, + int bytesToRead, + int& cefBytesRead, + CefRefPtr[CefCallback] cefCallback + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + cdef py_bool returnValue + cdef list dataOut + cdef list bytesReadOut + cdef PyCallback pyCallback + cdef char* tempData + cdef int tempDataLength + cdef int pyBytesRead + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + dataOut = [""] + bytesReadOut = [0] + pyCallback = CreatePyCallback(cefCallback) + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("ReadResponse") + if userCallback: + returnValue = userCallback(dataOut, bytesToRead, bytesReadOut, + pyCallback) + pyBytesRead = int(bytesReadOut[0]) + if dataOut[0] and IsString(dataOut[0]): + # The tempData pointer is tied to the lifetime + # of dataOut[0] string. + tempData = dataOut[0] + memcpy(cefDataOut, tempData, len(dataOut[0])) + assert pyBytesRead >= 0, "bytesReadOut < 0" + (&cefBytesRead)[0] = pyBytesRead + # True should be returned now. + else: + (&cefBytesRead)[0] = 0 + # Either: + # 1. True should be returned and callback.Continue() + # called at a later time. + # 2. False returned to indicate response completion. + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool ResourceHandler_CanGetCookie( + int resourceHandlerId, + const CefCookie& cefCookie + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + cdef py_bool returnValue + cdef PyCookie pyCookie + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + pyCookie = CreatePyCookie(cefCookie) + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("CanGetCookie") + if userCallback: + returnValue = userCallback(pyCookie) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public cpp_bool ResourceHandler_CanSetCookie( + int resourceHandlerId, + const CefCookie& cefCookie + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + cdef py_bool returnValue + cdef PyCookie pyCookie + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + pyCookie = CreatePyCookie(cefCookie) + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("CanSetCookie") + if userCallback: + returnValue = userCallback(pyCookie) + return bool(returnValue) + return False + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void ResourceHandler_Cancel( + int resourceHandlerId + ) except * with gil: + cdef PyResourceHandler pyResourceHandler + cdef object userCallback + try: + assert IsThread(TID_IO), "Must be called on the IO thread" + pyResourceHandler = GetPyResourceHandler(resourceHandlerId) + if pyResourceHandler: + userCallback = pyResourceHandler.GetCallback("Cancel") + if userCallback: + userCallback() + return + return + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) \ No newline at end of file diff --git a/cefpython/response_cef1.pyx b/cefpython/response_cef1.pyx new file mode 100644 index 00000000..fd7ee7ee --- /dev/null +++ b/cefpython/response_cef1.pyx @@ -0,0 +1,102 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PyResponse CreatePyResponse(CefRefPtr[CefResponse] cefResponse): + cdef PyResponse pyResponse = PyResponse() + pyResponse.cefResponse = cefResponse + return pyResponse + +cdef class PyResponse: + cdef CefRefPtr[CefResponse] cefResponse + + cdef CefRefPtr[CefResponse] GetCefResponse(self + ) except *: + if self.cefResponse != NULL and self.cefResponse.get(): + return self.cefResponse + raise Exception("CefResponse was destroyed, you cannot use this object anymore") + + cpdef int GetStatus(self) except *: + return self.GetCefResponse().get().GetStatus() + + cpdef py_void SetStatus(self, int status): + assert type(status) == int, ("Response.SetStatus() failed: status param is not an int") + self.GetCefResponse().get().SetStatus(status) + + cpdef str GetStatusText(self): + return CefToPyString(self.GetCefResponse().get().GetStatusText()) + + cpdef py_void SetStatusText(self, py_string statusText): + assert type(statusText) in (str, unicode, bytes), ( + "Response.SetStatusText() failed: statusText param is not a string") + cdef CefString cefStatusText + PyToCefString(statusText, cefStatusText) + self.GetCefResponse().get().SetStatusText(cefStatusText) + + cpdef str GetMimeType(self): + return CefToPyString(self.GetCefResponse().get().GetMimeType()) + + cpdef py_void SetMimeType(self, py_string mimeType): + assert type(mimeType) in (str, unicode, bytes), ( + "Response.SetMimeType() failed: mimeType param is not a string") + cdef CefString cefMimeType + PyToCefString(mimeType, cefMimeType) + self.GetCefResponse().get().SetMimeType(cefMimeType) + + cpdef str GetHeader(self, py_string name): + assert type(name) in (str, unicode, bytes), ( + "Response.GetHeader() failed: name param is not a string") + cdef CefString cefName + PyToCefString(name, cefName) + return CefToPyString(self.GetCefResponse().get().GetHeader(cefName)) + + cpdef dict GetHeaderMap(self): + cdef list headerMultimap = self.GetHeaderMultimap() + cdef dict headerMap = {} + cdef tuple headerTuple + for headerTuple in headerMultimap: + key = headerTuple[0] + value = headerTuple[1] + headerMap[key] = value + return headerMap + + cpdef list GetHeaderMultimap(self): + cdef cpp_multimap[CefString, CefString] cefHeaderMap + self.GetCefResponse().get().GetHeaderMap(cefHeaderMap) + cdef list pyHeaderMultimap = [] + cdef cpp_multimap[CefString, CefString].iterator iterator = ( + cefHeaderMap.begin()) + cdef CefString cefKey + cdef CefString cefValue + cdef str pyKey + cdef str pyValue + while iterator != cefHeaderMap.end(): + cefKey = deref(iterator).first + cefValue = deref(iterator).second + pyKey = CefToPyString(cefKey) + pyValue = CefToPyString(cefValue) + pyHeaderMultimap.append((pyKey, pyValue)) + preinc(iterator) + return pyHeaderMultimap + + cpdef py_void SetHeaderMap(self, dict headerMap): + assert len(headerMap) > 0, "headerMap param is empty" + cpdef list headerMultimap = [] + cdef object key + for key in headerMap: + headerMultimap.append((str(key), str(headerMap[key]))) + self.SetHeaderMultimap(headerMultimap) + + cpdef py_void SetHeaderMultimap(self, list headerMultimap): + assert len(headerMultimap) > 0, "headerMultimap param is empty" + cdef cpp_multimap[CefString, CefString] cefHeaderMap + cdef CefString cefKey + cdef CefString cefValue + cdef cpp_pair[CefString, CefString] pair + cdef tuple headerTuple + for headerTuple in headerMultimap: + PyToCefString(str(headerTuple[0]), cefKey) + PyToCefString(str(headerTuple[1]), cefValue) + pair.first, pair.second = cefKey, cefValue + cefHeaderMap.insert(pair) + self.GetCefResponse().get().SetHeaderMap(cefHeaderMap) diff --git a/cefpython/response_cef3.pyx b/cefpython/response_cef3.pyx new file mode 100644 index 00000000..f015affc --- /dev/null +++ b/cefpython/response_cef3.pyx @@ -0,0 +1,105 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PyResponse CreatePyResponse(CefRefPtr[CefResponse] cefResponse): + cdef PyResponse pyResponse = PyResponse() + pyResponse.cefResponse = cefResponse + return pyResponse + +cdef class PyResponse: + cdef CefRefPtr[CefResponse] cefResponse + + cdef CefRefPtr[CefResponse] GetCefResponse(self + ) except *: + if self.cefResponse != NULL and self.cefResponse.get(): + return self.cefResponse + raise Exception("CefResponse was destroyed, you cannot use this object anymore") + + cpdef py_bool IsReadOnly(self): + return self.GetCefResponse().get().IsReadOnly() + + cpdef int GetStatus(self) except *: + return self.GetCefResponse().get().GetStatus() + + cpdef py_void SetStatus(self, int status): + assert type(status) == int, ("Response.SetStatus() failed: status param is not an int") + self.GetCefResponse().get().SetStatus(status) + + cpdef str GetStatusText(self): + return CefToPyString(self.GetCefResponse().get().GetStatusText()) + + cpdef py_void SetStatusText(self, py_string statusText): + assert type(statusText) in (str, unicode, bytes), ( + "Response.SetStatusText() failed: statusText param is not a string") + cdef CefString cefStatusText + PyToCefString(statusText, cefStatusText) + self.GetCefResponse().get().SetStatusText(cefStatusText) + + cpdef str GetMimeType(self): + return CefToPyString(self.GetCefResponse().get().GetMimeType()) + + cpdef py_void SetMimeType(self, py_string mimeType): + assert type(mimeType) in (str, unicode, bytes), ( + "Response.SetMimeType() failed: mimeType param is not a string") + cdef CefString cefMimeType + PyToCefString(mimeType, cefMimeType) + self.GetCefResponse().get().SetMimeType(cefMimeType) + + cpdef str GetHeader(self, py_string name): + assert type(name) in (str, unicode, bytes), ( + "Response.GetHeader() failed: name param is not a string") + cdef CefString cefName + PyToCefString(name, cefName) + return CefToPyString(self.GetCefResponse().get().GetHeader(cefName)) + + cpdef dict GetHeaderMap(self): + cdef list headerMultimap = self.GetHeaderMultimap() + cdef dict headerMap = {} + cdef tuple headerTuple + for headerTuple in headerMultimap: + key = headerTuple[0] + value = headerTuple[1] + headerMap[key] = value + return headerMap + + cpdef list GetHeaderMultimap(self): + cdef cpp_multimap[CefString, CefString] cefHeaderMap + self.GetCefResponse().get().GetHeaderMap(cefHeaderMap) + cdef list pyHeaderMultimap = [] + cdef cpp_multimap[CefString, CefString].iterator iterator = ( + cefHeaderMap.begin()) + cdef CefString cefKey + cdef CefString cefValue + cdef str pyKey + cdef str pyValue + while iterator != cefHeaderMap.end(): + cefKey = deref(iterator).first + cefValue = deref(iterator).second + pyKey = CefToPyString(cefKey) + pyValue = CefToPyString(cefValue) + pyHeaderMultimap.append((pyKey, pyValue)) + preinc(iterator) + return pyHeaderMultimap + + cpdef py_void SetHeaderMap(self, dict headerMap): + assert len(headerMap) > 0, "headerMap param is empty" + cpdef list headerMultimap = [] + cdef object key + for key in headerMap: + headerMultimap.append((str(key), str(headerMap[key]))) + self.SetHeaderMultimap(headerMultimap) + + cpdef py_void SetHeaderMultimap(self, list headerMultimap): + assert len(headerMultimap) > 0, "headerMultimap param is empty" + cdef cpp_multimap[CefString, CefString] cefHeaderMap + cdef CefString cefKey + cdef CefString cefValue + cdef cpp_pair[CefString, CefString] pair + cdef tuple headerTuple + for headerTuple in headerMultimap: + PyToCefString(str(headerTuple[0]), cefKey) + PyToCefString(str(headerTuple[1]), cefValue) + pair.first, pair.second = cefKey, cefValue + cefHeaderMap.insert(pair) + self.GetCefResponse().get().SetHeaderMap(cefHeaderMap) diff --git a/cefpython/settings.pyx b/cefpython/settings.pyx new file mode 100644 index 00000000..79b2e975 --- /dev/null +++ b/cefpython/settings.pyx @@ -0,0 +1,484 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# More options/flags can be specified for Chromium through +# CefApp::OnBeforeCommandLineProcessing(), see comment 10 by Marshall: +# https://code.google.com/p/chromiumembedded/issues/detail?id=878#c10 + +IF CEF_VERSION == 3: + LOGSEVERITY_DEFAULT = cef_types.LOGSEVERITY_DEFAULT +LOGSEVERITY_VERBOSE = cef_types.LOGSEVERITY_VERBOSE +LOGSEVERITY_INFO = cef_types.LOGSEVERITY_INFO +LOGSEVERITY_WARNING = cef_types.LOGSEVERITY_WARNING +LOGSEVERITY_ERROR = cef_types.LOGSEVERITY_ERROR +LOGSEVERITY_ERROR_REPORT = cef_types.LOGSEVERITY_ERROR_REPORT +LOGSEVERITY_DISABLE = cef_types.LOGSEVERITY_DISABLE + +IF UNAME_SYSNAME == "Windows": + IF CEF_VERSION == 1: + ANGLE_IN_PROCESS = cef_types_win.ANGLE_IN_PROCESS + ANGLE_IN_PROCESS_COMMAND_BUFFER = cef_types_win.ANGLE_IN_PROCESS_COMMAND_BUFFER + DESKTOP_IN_PROCESS = cef_types_win.DESKTOP_IN_PROCESS + DESKTOP_IN_PROCESS_COMMAND_BUFFER = cef_types_win.DESKTOP_IN_PROCESS_COMMAND_BUFFER + +cdef void SetApplicationSettings( + dict appSettings, + CefSettings* cefAppSettings + ) except *: + cdef CefString* cefString + + for key in appSettings: + # Setting string: CefString(&browserDefaults.default_encoding).FromASCII("UTF-8"); + # cefString = CefString(&cefSettings.user_agent) + # cefString.FromASCII(settings[key]) + + # --------------------------------------------------------------------- + # CEF 1 + # --------------------------------------------------------------------- + IF CEF_VERSION == 1: + if key == "string_encoding"\ + or key == "debug": + # CEF Python only options. These are not to be found in CEF. + continue + elif key == "multi_threaded_message_loop": + cefAppSettings.multi_threaded_message_loop = bool(appSettings[key]) + elif key == "cache_path": + cefString = new CefString(&cefAppSettings.cache_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "user_agent": + cefString = new CefString(&cefAppSettings.user_agent) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "product_version": + cefString = new CefString(&cefAppSettings.product_version) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "log_file": + cefString = new CefString(&cefAppSettings.log_file) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "locale": + cefString = new CefString(&cefAppSettings.locale) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "log_severity": + cefAppSettings.log_severity = int(appSettings[key]) + elif key == "release_dcheck_enabled": + cefAppSettings.release_dcheck_enabled = bool(appSettings[key]) + elif key == "graphics_implementation" and platform.system() == "Windows": + # Cython compiler error: cef_types_win not defined on linux + IF UNAME_SYSNAME == "Windows": + cefAppSettings.graphics_implementation = int(appSettings[key]) + elif key == "local_storage_quota": + cefAppSettings.local_storage_quota = int(appSettings[key]) + elif key == "session_storage_quota": + cefAppSettings.session_storage_quota = int(appSettings[key]) + elif key == "javascript_flags": + cefString = new CefString(&cefAppSettings.javascript_flags) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "auto_detect_proxy_settings_enabled": + IF UNAME_SYSNAME == "Windows": + cefAppSettings.auto_detect_proxy_settings_enabled = bool(appSettings[key]) + ELSE: + raise Exception("auto_detect_proxy_settings_enabled is a Windows-only option") + elif key == "resources_dir_path": + cefString = new CefString(&cefAppSettings.resources_dir_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "locales_dir_path": + cefString = new CefString(&cefAppSettings.locales_dir_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "pack_loading_disabled": + cefAppSettings.pack_loading_disabled = bool(appSettings[key]) + elif key == "uncaught_exception_stack_size": + cefAppSettings.uncaught_exception_stack_size = int(appSettings[key]) + else: + raise Exception("Invalid appSettings key: %s" % key) + + # --------------------------------------------------------------------- + # CEF 3 + # --------------------------------------------------------------------- + ELIF CEF_VERSION == 3: + if key == "string_encoding"\ + or key == "debug"\ + or key == "unique_request_context_per_browser"\ + or key == "downloads_enabled"\ + or key == "context_menu" \ + or key == "auto_zooming": + # CEF Python only options. These are not to be found in CEF. + continue + elif key == "multi_threaded_message_loop": + cefAppSettings.multi_threaded_message_loop = bool(appSettings[key]) + elif key == "cache_path": + cefString = new CefString(&cefAppSettings.cache_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "persist_session_cookies": + cefAppSettings.persist_session_cookies = bool(appSettings[key]) + elif key == "user_agent": + cefString = new CefString(&cefAppSettings.user_agent) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "product_version": + cefString = new CefString(&cefAppSettings.product_version) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "log_file": + cefString = new CefString(&cefAppSettings.log_file) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "locale": + cefString = new CefString(&cefAppSettings.locale) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "log_severity": + cefAppSettings.log_severity = int(appSettings[key]) + elif key == "release_dcheck_enabled": + cefAppSettings.release_dcheck_enabled = bool(appSettings[key]) + elif key == "javascript_flags": + cefString = new CefString(&cefAppSettings.javascript_flags) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "resources_dir_path": + cefString = new CefString(&cefAppSettings.resources_dir_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "locales_dir_path": + cefString = new CefString(&cefAppSettings.locales_dir_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "pack_loading_disabled": + cefAppSettings.pack_loading_disabled = bool(appSettings[key]) + elif key == "uncaught_exception_stack_size": + cefAppSettings.uncaught_exception_stack_size = int(appSettings[key]) + elif key == "single_process": + cefAppSettings.single_process = bool(appSettings[key]) + elif key == "browser_subprocess_path": + cefString = new CefString(&cefAppSettings.browser_subprocess_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString + elif key == "command_line_args_disabled": + cefAppSettings.command_line_args_disabled = bool(appSettings[key]) + elif key == "remote_debugging_port": + cefAppSettings.remote_debugging_port = int(appSettings[key]) + elif key == "ignore_certificate_errors": + cefAppSettings.ignore_certificate_errors = bool(appSettings[key]) + elif key == "background_color": + cefAppSettings.background_color = \ + int(appSettings[key]) + else: + raise Exception("Invalid appSettings key: %s" % key) + +cdef void SetBrowserSettings( + dict browserSettings, + CefBrowserSettings* cefBrowserSettings + ) except *: + cdef CefString* cefString + + for key in browserSettings: + + IF CEF_VERSION == 1: + + if key == "animation_frame_rate": + cefBrowserSettings.animation_frame_rate = int(browserSettings[key]) + elif key == "drag_drop_disabled": + cefBrowserSettings.drag_drop_disabled = bool(browserSettings[key]) + elif key == "load_drops_disabled": + cefBrowserSettings.load_drops_disabled = bool(browserSettings[key]) + elif key == "history_disabled": + cefBrowserSettings.history_disabled = bool(browserSettings[key]) + elif key == "standard_font_family": + cefString = new CefString(&cefBrowserSettings.standard_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "fixed_font_family": + cefString = new CefString(&cefBrowserSettings.fixed_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "serif_font_family": + cefString = new CefString(&cefBrowserSettings.serif_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "sans_serif_font_family": + cefString = new CefString(&cefBrowserSettings.sans_serif_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "cursive_font_family": + cefString = new CefString(&cefBrowserSettings.cursive_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "fantasy_font_family": + cefString = new CefString(&cefBrowserSettings.fantasy_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "default_font_size": + cefBrowserSettings.default_font_size = int(browserSettings[key]) + elif key == "default_fixed_font_size": + cefBrowserSettings.default_fixed_font_size = int(browserSettings[key]) + elif key == "minimum_font_size": + cefBrowserSettings.minimum_font_size = int(browserSettings[key]) + elif key == "minimum_logical_font_size": + cefBrowserSettings.minimum_logical_font_size = int(browserSettings[key]) + elif key == "remote_fonts_disabled": + cefBrowserSettings.remote_fonts_disabled = bool(browserSettings[key]) + elif key == "default_encoding": + cefString = new CefString(&cefBrowserSettings.default_encoding) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "encoding_detector_enabled": + cefBrowserSettings.encoding_detector_enabled = bool(browserSettings[key]) + elif key == "javascript_disabled": + cefBrowserSettings.javascript_disabled = bool(browserSettings[key]) + elif key == "javascript_open_windows_disallowed": + cefBrowserSettings.javascript_open_windows_disallowed = bool(browserSettings[key]) + elif key == "javascript_close_windows_disallowed": + cefBrowserSettings.javascript_close_windows_disallowed = bool(browserSettings[key]) + elif key == "javascript_access_clipboard_disallowed": + cefBrowserSettings.javascript_access_clipboard_disallowed = bool(browserSettings[key]) + elif key == "dom_paste_disabled": + cefBrowserSettings.dom_paste_disabled = bool(browserSettings[key]) + elif key == "caret_browsing_enabled": + cefBrowserSettings.caret_browsing_enabled = bool(browserSettings[key]) + elif key == "java_disabled": + cefBrowserSettings.java_disabled = bool(browserSettings[key]) + elif key == "plugins_disabled": + cefBrowserSettings.plugins_disabled = bool(browserSettings[key]) + elif key == "universal_access_from_file_urls_allowed": + cefBrowserSettings.universal_access_from_file_urls_allowed = bool(browserSettings[key]) + elif key == "file_access_from_file_urls_allowed": + cefBrowserSettings.file_access_from_file_urls_allowed = bool(browserSettings[key]) + elif key == "web_security_disabled": + cefBrowserSettings.web_security_disabled = bool(browserSettings[key]) + elif key == "xss_auditor_enabled": + cefBrowserSettings.xss_auditor_enabled = bool(browserSettings[key]) + elif key == "image_load_disabled": + cefBrowserSettings.image_load_disabled = bool(browserSettings[key]) + elif key == "shrink_standalone_images_to_fit": + cefBrowserSettings.shrink_standalone_images_to_fit = bool(browserSettings[key]) + elif key == "site_specific_quirks_disabled": + cefBrowserSettings.site_specific_quirks_disabled = bool(browserSettings[key]) + elif key == "text_area_resize_disabled": + cefBrowserSettings.text_area_resize_disabled = bool(browserSettings[key]) + elif key == "page_cache_disabled": + cefBrowserSettings.page_cache_disabled = bool(browserSettings[key]) + elif key == "tab_to_links_disabled": + cefBrowserSettings.tab_to_links_disabled = bool(browserSettings[key]) + elif key == "hyperlink_auditing_disabled": + cefBrowserSettings.hyperlink_auditing_disabled = bool(browserSettings[key]) + elif key == "user_style_sheet_enabled": + cefBrowserSettings.user_style_sheet_enabled = bool(browserSettings[key]) + elif key == "user_style_sheet_location": + cefString = new CefString(&cefBrowserSettings.user_style_sheet_location) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "author_and_user_styles_disabled": + cefBrowserSettings.author_and_user_styles_disabled = bool(browserSettings[key]) + elif key == "local_storage_disabled": + cefBrowserSettings.local_storage_disabled = bool(browserSettings[key]) + elif key == "databases_disabled": + cefBrowserSettings.databases_disabled = bool(browserSettings[key]) + elif key == "application_cache_disabled": + cefBrowserSettings.application_cache_disabled = bool(browserSettings[key]) + elif key == "webgl_disabled": + cefBrowserSettings.webgl_disabled = bool(browserSettings[key]) + elif key == "accelerated_compositing_enabled": + cefBrowserSettings.accelerated_compositing_enabled = bool(browserSettings[key]) + elif key == "accelerated_layers_disabled": + cefBrowserSettings.accelerated_layers_disabled = bool(browserSettings[key]) + elif key == "accelerated_video_disabled": + cefBrowserSettings.accelerated_video_disabled = bool(browserSettings[key]) + elif key == "accelerated_2d_canvas_disabled": + cefBrowserSettings.accelerated_2d_canvas_disabled = bool(browserSettings[key]) + elif key == "accelerated_filters_disabled": + cefBrowserSettings.accelerated_filters_disabled = bool(browserSettings[key]) + elif key == "accelerated_plugins_disabled": + cefBrowserSettings.accelerated_plugins_disabled = bool(browserSettings[key]) + elif key == "developer_tools_disabled": + cefBrowserSettings.developer_tools_disabled = bool(browserSettings[key]) + elif key == "fullscreen_enabled": + cefBrowserSettings.fullscreen_enabled = bool(browserSettings[key]) + else: + raise Exception("Invalid browserSettings key: %s" % key) + + ELIF CEF_VERSION == 3: + + if key == "standard_font_family": + cefString = new CefString(&cefBrowserSettings.standard_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "fixed_font_family": + cefString = new CefString(&cefBrowserSettings.fixed_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "serif_font_family": + cefString = new CefString(&cefBrowserSettings.serif_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "sans_serif_font_family": + cefString = new CefString(&cefBrowserSettings.sans_serif_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "cursive_font_family": + cefString = new CefString(&cefBrowserSettings.cursive_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "fantasy_font_family": + cefString = new CefString(&cefBrowserSettings.fantasy_font_family) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "default_font_size": + cefBrowserSettings.default_font_size = int(browserSettings[key]) + elif key == "default_fixed_font_size": + cefBrowserSettings.default_fixed_font_size = int(browserSettings[key]) + elif key == "minimum_font_size": + cefBrowserSettings.minimum_font_size = int(browserSettings[key]) + elif key == "minimum_logical_font_size": + cefBrowserSettings.minimum_logical_font_size = int(browserSettings[key]) + elif key == "default_encoding": + cefString = new CefString(&cefBrowserSettings.default_encoding) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "user_style_sheet_location": + cefString = new CefString(&cefBrowserSettings.user_style_sheet_location) + PyToCefStringPointer(browserSettings[key], cefString) + del cefString + elif key == "remote_fonts_disabled": + if browserSettings[key]: + cefBrowserSettings.remote_fonts = cef_types.STATE_DISABLED + else: + cefBrowserSettings.remote_fonts = cef_types.STATE_ENABLED + elif key == "javascript_disabled": + if browserSettings[key]: + cefBrowserSettings.javascript = cef_types.STATE_DISABLED + else: + cefBrowserSettings.javascript = cef_types.STATE_ENABLED + elif key == "javascript_open_windows_disallowed": + if browserSettings[key]: + cefBrowserSettings.javascript_open_windows = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.javascript_open_windows = ( + cef_types.STATE_ENABLED) + elif key == "javascript_close_windows_disallowed": + if browserSettings[key]: + cefBrowserSettings.javascript_close_windows = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.javascript_close_windows = ( + cef_types.STATE_ENABLED) + elif key == "javascript_access_clipboard_disallowed": + if browserSettings[key]: + cefBrowserSettings.javascript_access_clipboard = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.javascript_access_clipboard = ( + cef_types.STATE_ENABLED) + elif key == "dom_paste_disabled": + if browserSettings[key]: + cefBrowserSettings.javascript_dom_paste = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.javascript_dom_paste = ( + cef_types.STATE_ENABLED) + elif key == "caret_browsing_enabled": + if browserSettings[key]: + cefBrowserSettings.caret_browsing = ( + cef_types.STATE_ENABLED) + else: + cefBrowserSettings.caret_browsing = ( + cef_types.STATE_DISABLED) + elif key == "java_disabled": + if browserSettings[key]: + cefBrowserSettings.java = cef_types.STATE_DISABLED + else: + cefBrowserSettings.java = cef_types.STATE_ENABLED + elif key == "plugins_disabled": + if browserSettings[key]: + cefBrowserSettings.plugins = cef_types.STATE_DISABLED + else: + cefBrowserSettings.plugins = cef_types.STATE_ENABLED + elif key == "universal_access_from_file_urls_allowed": + if browserSettings[key]: + cefBrowserSettings.universal_access_from_file_urls = ( + cef_types.STATE_ENABLED) + else: + cefBrowserSettings.universal_access_from_file_urls = ( + cef_types.STATE_DISABLED) + elif key == "file_access_from_file_urls_allowed": + if browserSettings[key]: + cefBrowserSettings.file_access_from_file_urls = ( + cef_types.STATE_ENABLED) + else: + cefBrowserSettings.file_access_from_file_urls = ( + cef_types.STATE_DISABLED) + elif key == "web_security_disabled": + if browserSettings[key]: + cefBrowserSettings.web_security = cef_types.STATE_DISABLED + else: + cefBrowserSettings.web_security = cef_types.STATE_ENABLED + elif key == "image_load_disabled": + if browserSettings[key]: + cefBrowserSettings.image_loading = cef_types.STATE_DISABLED + else: + cefBrowserSettings.image_loading = cef_types.STATE_ENABLED + elif key == "shrink_standalone_images_to_fit": + if browserSettings[key]: + cefBrowserSettings.image_shrink_standalone_to_fit = ( + cef_types.STATE_ENABLED) + else: + cefBrowserSettings.image_shrink_standalone_to_fit = ( + cef_types.STATE_DISABLED) + elif key == "text_area_resize_disabled": + if browserSettings[key]: + cefBrowserSettings.text_area_resize = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.text_area_resize = ( + cef_types.STATE_ENABLED) + elif key == "tab_to_links_disabled": + if browserSettings[key]: + cefBrowserSettings.tab_to_links = cef_types.STATE_DISABLED + else: + cefBrowserSettings.tab_to_links = cef_types.STATE_ENABLED + elif key == "author_and_user_styles_disabled": + if browserSettings[key]: + cefBrowserSettings.author_and_user_styles = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.author_and_user_styles = ( + cef_types.STATE_ENABLED) + elif key == "local_storage_disabled": + if browserSettings[key]: + cefBrowserSettings.local_storage = cef_types.STATE_DISABLED + else: + cefBrowserSettings.local_storage = cef_types.STATE_ENABLED + elif key == "databases_disabled": + if browserSettings[key]: + cefBrowserSettings.databases = cef_types.STATE_DISABLED + else: + cefBrowserSettings.databases = cef_types.STATE_ENABLED + elif key == "application_cache_disabled": + if browserSettings[key]: + cefBrowserSettings.application_cache = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.application_cache = ( + cef_types.STATE_ENABLED) + elif key == "webgl_disabled": + if browserSettings[key]: + cefBrowserSettings.webgl = cef_types.STATE_DISABLED + else: + cefBrowserSettings.webgl = cef_types.STATE_ENABLED + elif key == "accelerated_compositing_disabled": + if browserSettings[key]: + cefBrowserSettings.accelerated_compositing = ( + cef_types.STATE_DISABLED) + else: + cefBrowserSettings.accelerated_compositing = ( + cef_types.STATE_ENABLED) + else: + raise Exception("Invalid browserSettings key: %s" % key) diff --git a/cefpython/stream.pyx b/cefpython/stream.pyx new file mode 100644 index 00000000..ad823b75 --- /dev/null +++ b/cefpython/stream.pyx @@ -0,0 +1,35 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef class PyStreamReader: + cdef CefRefPtr[CefStreamReader] cefStreamReader + + cdef cpp_bool HasCefStreamReader(self) except *: + if self.cefStreamReader != NULL and self.cefStreamReader.get(): + return True + return False + + cdef CefRefPtr[CefStreamReader] GetCefStreamReader(self) except *: + if self.HasCefStreamReader(): + return self.cefStreamReader + return NULL + + cpdef py_void SetFile(self, py_string file): + if os.path.exists(file): + self.cefStreamReader = cef_stream_static.CreateForFile( + PyToCefStringValue(file)) + else: + raise Exception("File does not exist: %s" % file) + + cpdef py_void SetData(self, py_string data): + cdef cpp_string cppString = data + # CreateForData() requires "void* data", we can't just pass + # cppString.c_str() as it is const, we need to copy all data. + cdef void* voidData + cdef int dataLength = cppString.length() + voidData = malloc(dataLength) + memcpy(voidData, cppString.c_str(), dataLength) + self.cefStreamReader = cef_stream_static.CreateForData( + voidData, dataLength) + free(voidData) diff --git a/cefpython/string_utils.pyx b/cefpython/string_utils.pyx new file mode 100644 index 00000000..e478ebb9 --- /dev/null +++ b/cefpython/string_utils.pyx @@ -0,0 +1,123 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# TODO: cleanup the code in string_utils.pyx and string_utils_win.pyx, +# see this topic for a review of the code in this file, see the +# posts by Stefan Behnel: +# https://groups.google.com/d/topic/cython-users/VICzhVn-zPw/discussion + +# TODO: make this configurable through ApplicationSettings. +UNICODE_ENCODE_ERRORS = "replace" +BYTES_DECODE_ERRORS = "replace" + +# Any bytes/unicode encoding and decoding in cefpython should +# be performed only using functions from this file - let's +# keep it in one place for future fixes - see Issue 60 ("Strings +# should be unicode by default, if bytes is required make it +# explicit"). + +cdef py_string AnyToPyString(object value): + cdef object valueType = type(value) + if valueType == str or valueType == bytes: + return value + elif PY_MAJOR_VERSION < 3 and valueType == unicode: + # The unicode type is not defined in Python 3 + return value + else: + return "" + +cdef py_string CharToPyString( + const char* charString): + if PY_MAJOR_VERSION < 3: + return charString + else: + return ((charString).decode( + g_applicationSettings["string_encoding"], + errors=BYTES_DECODE_ERRORS)) + +# cdef py_string CppToPyString( +# cpp_string cppString): +# if PY_MAJOR_VERSION < 3: +# return cppString +# else: +# return ((cppString).decode( +# g_applicationSettings["string_encoding"], +# errors=BYTES_DECODE_ERRORS)) + +# cdef cpp_string PyToCppString(py_string pyString) except *: +# cdef cpp_string cppString = pyString +# return cppString + +cdef py_string CefToPyString( + ConstCefString& cefString): + cdef cpp_string cppString + if cefString.empty(): + return "" + IF UNAME_SYSNAME == "Windows": + cdef wchar_t* wcharstr = cefString.c_str() + return WidecharToPyString(wcharstr) + ELSE: + cppString = cefString.ToString() + if PY_MAJOR_VERSION < 3: + return cppString + else: + return ((cppString).decode( + g_applicationSettings["string_encoding"], + errors=BYTES_DECODE_ERRORS)) + +cdef void PyToCefString( + py_string pyString, + CefString& cefString + ) except *: + if PY_MAJOR_VERSION < 3: + if type(pyString) == unicode: + pyString = (pyString.encode( + g_applicationSettings["string_encoding"], + errors=UNICODE_ENCODE_ERRORS)) + else: + # The unicode type is not defined in Python 3. + if type(pyString) == str: + pyString = (pyString.encode( + g_applicationSettings["string_encoding"], + errors=UNICODE_ENCODE_ERRORS)) + cdef cpp_string cppString = pyString + # Using cefString.FromASCII() will result in DCHECK failures + # when a non-ascii character is encountered. + cefString.FromString(cppString) + +cdef CefString PyToCefStringValue( + py_string pyString + ) except *: + cdef CefString cefString + PyToCefString(pyString, cefString) + return cefString + +cdef void PyToCefStringPointer( + py_string pyString, + CefString* cefString + ) except *: + if PY_MAJOR_VERSION < 3: + if type(pyString) == unicode: + pyString = (pyString.encode( + g_applicationSettings["string_encoding"], + errors=UNICODE_ENCODE_ERRORS)) + else: + # The unicode type is not defined in Python 3. + if type(pyString) == str: + pyString = (pyString.encode( + g_applicationSettings["string_encoding"], + errors=UNICODE_ENCODE_ERRORS)) + + cdef cpp_string cppString = pyString + # When used cefString.FromASCII(), a DCHECK failed + # when passed a unicode string. + cefString.FromString(cppString) + +cdef py_string VoidPtrToString(const void* data, size_t dataLength): + if PY_MAJOR_VERSION < 3: + return ((data)[:dataLength]) + else: + return (((data)[:dataLength]).decode( + g_applicationSettings["string_encoding"], + errors=BYTES_DECODE_ERRORS)) diff --git a/cefpython/string_utils_win.pyx b/cefpython/string_utils_win.pyx new file mode 100644 index 00000000..8b96d973 --- /dev/null +++ b/cefpython/string_utils_win.pyx @@ -0,0 +1,33 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef int wchar_t_size = 2 + +cdef void CharToWidechar(char* charString, wchar_t* wideString, int wideSize + ) except *: + cdef int copiedCharacters = MultiByteToWideChar( + CP_UTF8, 0, charString, -1, wideString, wideSize) + # MultiByteToWideChar does not include the NULL character + # when 0 bytes are written. + if wideSize > 0 and copiedCharacters == 0: + wideString[0] = 0 + +cdef py_string WidecharToPyString( + wchar_t* wcharString): + cdef int charBytes = WideCharToMultiByte( + CP_UTF8, 0, wcharString, -1, NULL, 0, NULL, NULL) + assert charBytes > 0, "WideCharToMultiByte() returned 0" + + cdef char* charString = malloc(charBytes * sizeof(char)) + cdef int copiedBytes = WideCharToMultiByte( + CP_UTF8, 0, wcharString, -1, charString, charBytes, NULL, NULL) + + # WideCharToMultiByte does not include the NULL character + # when 0 bytes are written. + if copiedBytes == 0: + charString[0] = 0; + + cdef py_string pyString = CharToPyString(charString) + free(charString) + return pyString diff --git a/cefpython/string_visitor_cef3.pyx b/cefpython/string_visitor_cef3.pyx new file mode 100644 index 00000000..aeeffb06 --- /dev/null +++ b/cefpython/string_visitor_cef3.pyx @@ -0,0 +1,71 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# ----------------------------------------------------------------------------- +# PyStringVisitor +# ----------------------------------------------------------------------------- + +cdef object g_userStringVisitors = weakref.WeakValueDictionary() +cdef int g_userStringVisitorMaxId = 0 + +cdef int StoreUserStringVisitor(object userStringVisitor) except *: + global g_userStringVisitorMaxId + global g_userStringVisitors + g_userStringVisitorMaxId += 1 + g_userStringVisitors[g_userStringVisitorMaxId] = userStringVisitor + return g_userStringVisitorMaxId + +cdef PyStringVisitor GetUserStringVisitor(int stringVisitorId): + global g_userStringVisitors + cdef object userStringVisitor + cdef PyStringVisitor pyStringVisitor + if stringVisitorId in g_userStringVisitors: + userStringVisitor = g_userStringVisitors[stringVisitorId] + pyStringVisitor = PyStringVisitor(userStringVisitor) + return pyStringVisitor + +cdef class PyStringVisitor: + cdef object userStringVisitor + + def __init__(self, object userStringVisitor): + self.userStringVisitor = userStringVisitor + + cdef object GetCallback(self, str funcName): + if self.userStringVisitor and ( + hasattr(self.userStringVisitor, funcName) and ( + callable(getattr(self.userStringVisitor, funcName)))): + return getattr(self.userStringVisitor, funcName) + +# ----------------------------------------------------------------------------- +# C++ StringVisitor +# ----------------------------------------------------------------------------- + +cdef CefRefPtr[CefStringVisitor] CreateStringVisitor( + object userStringVisitor) except *: + if not userStringVisitor: + raise Exception("userStringVisitor object missing") + if not hasattr(userStringVisitor, "Visit"): + raise Exception("userStringVisitor object is missing Visit() method") + cdef int stringVisitorId = StoreUserStringVisitor(userStringVisitor) + cdef CefRefPtr[CefStringVisitor] cefStringVisitor = ( + new StringVisitor(stringVisitorId)) + return cefStringVisitor + +cdef public void StringVisitor_Visit( + int stringVisitorId, + const CefString& string + ) except * with gil: + cdef str pyString + cdef PyStringVisitor userStringVisitor + cdef object callback + try: + pyString = CefToPyString(string) + userStringVisitor = GetUserStringVisitor(stringVisitorId) + if userStringVisitor: + callback = userStringVisitor.GetCallback("Visit") + if callback: + callback(pyString) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/task.pyx b/cefpython/task.pyx new file mode 100644 index 00000000..c7a08f17 --- /dev/null +++ b/cefpython/task.pyx @@ -0,0 +1,60 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +g_taskMaxId = 0 +g_tasks = {} + +def PostTask(int threadId, object func, *args): + global g_tasks, g_taskMaxId + + # Validate threadId. + if threadId not in g_browserProcessThreads: + raise Exception("PoastTask failed: requires a browser process thread") + + # Validate func. + if not IsFunctionOrMethod(type(func)): + raise Exception("PostTask failed: not a function nor method") + + # Params. + cdef list params = list(args) + + # Keep func and params until PyTaskRunnable is called. + g_taskMaxId += 1 + g_tasks[str(g_taskMaxId)] = { + "func": func, + "params": params + } + + # Call C++ wrapper. + cdef int cTaskId = int(g_taskMaxId) + with nogil: + PostTaskWrapper(threadId, cTaskId) + +cdef public void PyTaskRunnable(int taskId) except * with gil: + cdef object func + cdef list params + cdef object task + + try: + global g_tasks + + # Validate if task exist. + if str(taskId) not in g_tasks: + raise Exception("PyTaskRunnable failed: invalid taskId=%s" \ + % taskId) + + # Fetch task: func and params. + task = g_tasks[str(taskId)] + func = task["func"] + params = task["params"] + del g_tasks[str(taskId)] + + # Execute user func. + Debug("PyTaskRunnable: taskId=%s, func=%s" % (taskId, func.__name__)) + func(*params) + + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + diff --git a/cefpython/tests/test-launch.sh b/cefpython/tests/test-launch.sh new file mode 100755 index 00000000..16d247aa --- /dev/null +++ b/cefpython/tests/test-launch.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Usage: ./test-launch.sh 500 + +# When launching this test script more than once in current +# Linux session then the CEF initialization issue is hard +# to reproduce. The best results are when launching tests +# in a clean Ubuntu session, just log out and log in again, +# and run the test immediately. You could also run a few +# terminal sessions with several test scripts running +# simultaneously to simulate heavy overload. + +for ((i = 1; i <= $1; i++)); do + output=$(python ./../cef3/wx-subpackage/examples/sample2.py test-launch) + code=$? + if [[ $code != 0 || $output != *b8ba7d9945c22425328df2e21fbb64cd* ]]; then + echo "EXIT CODE: $code" + echo "OUTPUT: $output" + echo "ERROR!" + read -p "Press ENTER to exit" + exit $code + fi + echo RUN $i OK +done + +echo TEST SUCCEEDED +read -p "Press ENTER to exit" diff --git a/cefpython/time_utils.pyx b/cefpython/time_utils.pyx new file mode 100644 index 00000000..c5af81ba --- /dev/null +++ b/cefpython/time_utils.pyx @@ -0,0 +1,36 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef void DatetimeToCefTimeT(object pyDatetime, cef_time_t& timeT) except *: + if not isinstance(pyDatetime, datetime.datetime): + raise Exception("Expected object of type datetime.datetime") + timeT.year = pyDatetime.year + timeT.month = pyDatetime.month + timeT.day_of_week = pyDatetime.weekday() + timeT.day_of_month = pyDatetime.day + timeT.hour = pyDatetime.hour + timeT.minute = pyDatetime.minute + timeT.second = pyDatetime.second + # Milliseconds/microseconds are ignored. + timeT.millisecond = 0 + +cdef object CefTimeTToDatetime(cef_time_t timeT): + cdef int year = timeT.year + if year < datetime.MINYEAR: + year = datetime.MINYEAR + if year > datetime.MAXYEAR: + year = datetime.MAXYEAR + cdef int month = timeT.month + if month == 0: + month = 1 + cdef int day_of_month = timeT.day_of_month + if day_of_month == 0: + day_of_month = 1 + cdef int second = timeT.second + if second > 59: + # Ignore leap seconds as datetime.datetime() allows 0-59 only. + second = 59 + # Milliseconds/microseconds are ignored. + return datetime.datetime(year, month, day_of_month, + timeT.hour, timeT.minute, second) diff --git a/cefpython/utils.pyx b/cefpython/utils.pyx new file mode 100644 index 00000000..5453d99f --- /dev/null +++ b/cefpython/utils.pyx @@ -0,0 +1,134 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +TID_UI = cef_types.TID_UI +TID_DB = cef_types.TID_DB +TID_FILE = cef_types.TID_FILE +TID_FILE_USER_BLOCKING = cef_types.TID_FILE_USER_BLOCKING +TID_PROCESS_LAUNCHER = cef_types.TID_PROCESS_LAUNCHER +TID_CACHE = cef_types.TID_CACHE +TID_IO = cef_types.TID_IO +TID_RENDERER = cef_types.TID_RENDERER + +g_browserProcessThreads = [ + TID_UI, + TID_DB, + TID_FILE, + TID_FILE_USER_BLOCKING, + TID_CACHE, + TID_IO, +] + +cpdef py_bool IsString(object maybeString): + # In Python 2.7 string types are: 1) str/bytes 2) unicode. + # In Python 3 string types are: 1) bytes 2) str + if type(maybeString) == bytes or type(maybeString) == str \ + or (PY_MAJOR_VERSION < 3 and type(maybeString) == unicode): + return True + return False + +cpdef py_bool IsThread(int threadID): + return bool(CefCurrentlyOn(threadID)) + +# TODO: this function needs to accept unicode strings, use the +# logic from wxpython.py/ExceptHook to handle printing +# unicode strings and writing them to file (codecs.open). +# This change is required to work with Cython 0.20. + +cpdef object Debug(str msg): + if not g_debug: + return + msg = "[CEF Python] "+str(msg) + print(msg) + if g_debugFile: + try: + with open(g_debugFile, "a") as file: + file.write(msg+"\n") + except: + print("[CEF Python] WARNING: failed writing to debug file: %s" % ( + g_debugFile)) + + +cpdef str GetSystemError(): + IF UNAME_SYSNAME == "Windows": + cdef DWORD errorCode = GetLastError() + return "Error Code = %d" % (errorCode) + ELSE: + return "" + +cpdef str GetNavigateUrl(py_string url): + # Encode local file paths so that CEF can load them correctly: + # | some.html, some/some.html, D:\, /var, file:// + if re.search(r"^file:", url, re.I) or \ + re.search(r"^[a-zA-Z]:", url) or \ + not re.search(r"^[\w-]+:", url): + + # Function pathname2url will complain if url starts with "file://". + # CEF may also change local urls to "file:///C:/" - three slashes. + is_file_protocol = False + file_prefix = "" + file_prefixes = ["file:///", "file://"] + for file_prefix in file_prefixes: + if url.startswith(file_prefix): + is_file_protocol = True + # Remove the file:// prefix + url = url[len(file_prefix):] + break + + # Need to encode chinese characters in local file paths, + # otherwise CEF will try to encode them by itself. But it + # will fail in doing so. CEF will return the following string: + # >> %EF%BF%97%EF%BF%80%EF%BF%83%EF%BF%A6 + # But it should be: + # >> %E6%A1%8C%E9%9D%A2 + url = urllib_pathname2url(url) + + if is_file_protocol: + url = "%s%s" % (file_prefix, url) + + # If it is C:\ then colon was encoded. Decode it back. + url = re.sub(r"^([a-zA-Z])%3A", r"\1:", url) + + # Allow hash when loading urls. The pathname2url function + # replaced hashes with "%23" (Issue 114). + url = url.replace("%23", "#") + + return str(url) + +IF CEF_VERSION == 1: + cpdef py_bool IsKeyModifier(int key, int modifiers): + if key == KEY_NONE: + # Same as: return (KEY_CTRL & modifiers) != KEY_CTRL + # and (KEY_ALT & modifiers) != KEY_ALT + # and (KEY_SHIFT & modifiers) != KEY_SHIFT + return ((KEY_SHIFT | KEY_CTRL | KEY_ALT) & modifiers) == 0 + return (key & modifiers) == key + +cpdef str GetModuleDirectory(): + import re, os, platform + if platform.system() == "Linux" and os.getenv("CEFPYTHON3_PATH"): + # cefpython3 package __init__.py sets CEFPYTHON3_PATH. + # When cefpython3 is installed as debian package, this + # env variable is the only way of getting valid path. + return os.getenv("CEFPYTHON3_PATH") + if hasattr(sys, "frozen"): + path = os.path.dirname(sys.executable) + elif "__file__" in globals(): + path = os.path.dirname(os.path.realpath(__file__)) + else: + path = os.getcwd() + if platform.system() == "Windows": + # On linux this regexp would give: + # "\/home\/czarek\/cefpython\/cefpython\/cef1\/linux\/binaries" + path = re.sub(r"[/\\]+", re.escape(os.sep), path) + path = re.sub(r"[/\\]+$", "", path) + return str(path) + +cpdef py_bool IsFunctionOrMethod(object valueType): + if (valueType == types.FunctionType \ + or valueType == types.MethodType \ + or valueType == types.BuiltinFunctionType \ + or valueType == types.BuiltinMethodType): + return True + return False diff --git a/cefpython/v8context_handler_cef1.pyx b/cefpython/v8context_handler_cef1.pyx new file mode 100644 index 00000000..fe399446 --- /dev/null +++ b/cefpython/v8context_handler_cef1.pyx @@ -0,0 +1,172 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +V8_PROPERTY_ATTRIBUTE_NONE = cef_types.V8_PROPERTY_ATTRIBUTE_NONE +V8_PROPERTY_ATTRIBUTE_READONLY = cef_types.V8_PROPERTY_ATTRIBUTE_READONLY +V8_PROPERTY_ATTRIBUTE_DONTENUM = cef_types.V8_PROPERTY_ATTRIBUTE_DONTENUM +V8_PROPERTY_ATTRIBUTE_DONTDELETE = cef_types.V8_PROPERTY_ATTRIBUTE_DONTDELETE + +cdef public void V8ContextHandler_OnContextCreated( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefV8Context] cefContext + ) except * with gil: + # This handler may also be called by JavascriptBindings.Rebind(). + # This handler may be called multiple times for the same frame - rebinding. + + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + + cdef JavascriptBindings javascriptBindings + cdef dict javascriptFunctions + cdef dict javascriptProperties + cdef dict javascriptObjects + + cdef CefRefPtr[V8FunctionHandler] functionHandler + cdef CefRefPtr[CefV8Handler] v8Handler + cdef CefRefPtr[CefV8Value] v8Window + cdef CefRefPtr[CefV8Value] v8Function + cdef CefRefPtr[CefV8Value] v8Object + cdef CefRefPtr[CefV8Value] v8Method + + cdef CefString cefFunctionName + cdef CefString cefPropertyName + cdef CefString cefMethodName + cdef CefString cefObjectName + + cdef object key + cdef object value + cdef py_string functionName + cdef py_string objectName + + cdef object clientCallback + + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyBrowser.SetUserData("__v8ContextCreated", True) + pyFrame = GetPyFrame(cefFrame) + + javascriptBindings = pyBrowser.GetJavascriptBindings() + if not javascriptBindings: + return + + javascriptFunctions = javascriptBindings.GetFunctions() + javascriptProperties = javascriptBindings.GetProperties() + javascriptObjects = javascriptBindings.GetObjects() + + if not javascriptFunctions and not javascriptProperties and not javascriptObjects: + return + + # This checks GetBindToFrames/GetBindToPopups must also be made in both: + # FunctionHandler_Execute() and OnContextCreated(), so that calling + # a non-existent property on window object throws an error. + + if not pyFrame.IsMain() and not javascriptBindings.GetBindToFrames(): + return + + # This check is probably not needed, as GetPyBrowser() will already pass bindings=None, + # if this is a popup window and bindToPopups is False. + + if pyBrowser.IsPopup() and not javascriptBindings.GetBindToPopups(): + return + + v8Window = cefContext.get().GetGlobal() + + if javascriptProperties: + for key,value in javascriptProperties.items(): + key = str(key) + PyToCefString(key, cefPropertyName) + v8Window.get().SetValue( + cefPropertyName, + PyToV8Value(value, cefContext), + V8_PROPERTY_ATTRIBUTE_NONE) + + if javascriptFunctions or javascriptObjects: + functionHandler = new V8FunctionHandler() + functionHandler.get().SetContext(cefContext) + v8Handler = functionHandler.get() + + if javascriptFunctions: + for functionName in javascriptFunctions: + functionName = str(functionName) + PyToCefString(functionName, cefFunctionName) + v8Function = cef_v8_static.CreateFunction(cefFunctionName, v8Handler) + v8Window.get().SetValue(cefFunctionName, v8Function, V8_PROPERTY_ATTRIBUTE_NONE) + + if javascriptObjects: + for objectName in javascriptObjects: + v8Object = cef_v8_static.CreateObject(NULL) + PyToCefString(objectName, cefObjectName) + v8Window.get().SetValue( + cefObjectName, v8Object, V8_PROPERTY_ATTRIBUTE_NONE) + + for methodName in javascriptObjects[objectName]: + methodName = str(methodName) + # cefMethodName = "myobject.someMethod" + PyToCefString(objectName+"."+methodName, cefMethodName) + v8Method = cef_v8_static.CreateFunction(cefMethodName, v8Handler) + # cefMethodName = "someMethod" + PyToCefString(methodName, cefMethodName) + v8Object.get().SetValue( + cefMethodName, v8Method, V8_PROPERTY_ATTRIBUTE_NONE) + + # User defined callback. + clientCallback = pyBrowser.GetClientCallback("OnContextCreated") + if clientCallback: + clientCallback(pyBrowser, pyFrame) + + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void V8ContextHandler_OnContextReleased( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefV8Context] cefContext + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + # User defined callback. + clientCallback = pyBrowser.GetClientCallback("OnContextReleased") + if clientCallback: + clientCallback(pyBrowser, pyFrame) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void V8ContextHandler_OnUncaughtException( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefRefPtr[CefV8Context] cefContext, + CefRefPtr[CefV8Exception] cefException, + CefRefPtr[CefV8StackTrace] cefStackTrace + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef CefRefPtr[CefV8Exception] v8Exception + cdef CefV8Exception* v8ExceptionPointer + cdef object callback + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + + v8ExceptionPointer = cefException.get() + pyException = {} + pyException["lineNumber"] = v8ExceptionPointer.GetLineNumber() + pyException["message"] = CefToPyString(v8ExceptionPointer.GetMessage()) + pyException["scriptResourceName"] = CefToPyString( + v8ExceptionPointer.GetScriptResourceName()) + pyException["sourceLine"] = CefToPyString(v8ExceptionPointer.GetSourceLine()) + + pyStackTrace = CefV8StackTraceToPython(cefStackTrace) + + callback = pyBrowser.GetClientCallback("OnUncaughtException") + if callback: + callback(pyBrowser, pyFrame, pyException, pyStackTrace) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/v8context_handler_cef3.pyx b/cefpython/v8context_handler_cef3.pyx new file mode 100644 index 00000000..99dfed70 --- /dev/null +++ b/cefpython/v8context_handler_cef3.pyx @@ -0,0 +1,64 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# In CEF 3 there is no V8ContextHandler, the methods OnContextCreated(), +# OnContextReleased(), OnUncaughtException() are in CefRenderProcessHandler +# and are called in the Renderer process, we use process messaging to +# recreate these events in the Browser process, but the timing will be +# a bit delayed due to asynchronous way this is being done. + +cdef public void V8ContextHandler_OnContextCreated( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object clientCallback + try: + Debug("V8ContextHandler_OnContextCreated()") + pyBrowser = GetPyBrowser(cefBrowser) + pyBrowser.SetUserData("__v8ContextCreated", True) + pyFrame = GetPyFrame(cefFrame) + # User defined callback. + clientCallback = pyBrowser.GetClientCallback("OnContextCreated") + if clientCallback: + clientCallback(pyBrowser, pyFrame) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void V8ContextHandler_OnContextReleased( + int browserId, + int64 frameId + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef object clientCallback + try: + # Due to multi-process architecture in CEF 3, this function won't + # get called for the main frame in main browser. To send a message + # from the renderer process a parent browser is used. If this was + # a main frame then this would mean that the browser is being + # destroyed, thus we can't send a process message using this browser. + # There is no guarantee that this will get called for frames in the + # main browser, if the browser is destroyed shortly after the frames + # were released. + Debug("V8ContextHandler_OnContextReleased()") + pyBrowser = GetPyBrowserById(browserId) + pyFrame = GetPyFrameById(browserId, frameId) + if pyBrowser and pyFrame: + clientCallback = pyBrowser.GetClientCallback("OnContextReleased") + if clientCallback: + clientCallback(pyBrowser, pyFrame) + else: + if not pyBrowser: + Debug("V8ContextHandler_OnContextReleased() WARNING: " \ + "pyBrowser not found") + if not pyFrame: + Debug("V8ContextHandler_OnContextReleased() WARNING: " \ + "pyFrame not found") + RemovePyFrame(browserId, frameId) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/v8function_handler_cef1.pyx b/cefpython/v8function_handler_cef1.pyx new file mode 100644 index 00000000..98d72df3 --- /dev/null +++ b/cefpython/v8function_handler_cef1.pyx @@ -0,0 +1,89 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public cpp_bool V8FunctionHandler_Execute( + CefRefPtr[CefV8Context] v8Context, + int pythonCallbackId, + CefString& cefFuncName, + CefRefPtr[CefV8Value] cefObject, # receiver ('this' object) of the function. + CefV8ValueList& v8Arguments, + CefRefPtr[CefV8Value]& cefReturnValue, + CefString& cefException + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef JavascriptBindings javascriptBindings + cdef cpp_vector[CefRefPtr[CefV8Value]].iterator iterator + cdef CefRefPtr[CefV8Value] cefValue + cdef object pythonCallback + cdef list arguments + cdef str functionName + cdef object pyReturnValue + cdef object pyFunction + cdef str objectName + cdef str objectMethod + + try: + if pythonCallbackId: + pythonCallback = GetPythonCallback(pythonCallbackId) + + arguments = [] + iterator = v8Arguments.begin() + while iterator != v8Arguments.end(): + cefValue = deref(iterator) + arguments.append(V8ToPyValue(cefValue, v8Context)) + preinc(iterator) + + pyReturnValue = pythonCallback(*arguments) + # Can't use "arg = " for a referenced argument, bug in Cython, + # see comment in RequestHandler_OnProtocolExecution() for + # more details. + cefReturnValue.swap(PyToV8Value(pyReturnValue, v8Context)) + + return True + else: + pyBrowser = GetPyBrowser(v8Context.get().GetBrowser()) + pyFrame = GetPyFrame(v8Context.get().GetFrame()) + functionName = CefToPyString(cefFuncName) + + javascriptBindings = pyBrowser.GetJavascriptBindings() + if not javascriptBindings: + return False + + if functionName.find(".") == -1: + pyFunction = javascriptBindings.GetFunction(functionName) + if not pyFunction: + return False + else: + # functionName == "myobject.someMethod" + (objectName, methodName) = functionName.split(".") + pyFunction = javascriptBindings.GetObjectMethod(objectName, methodName) + if not pyFunction: + return False + + # GetBindToFrames/GetBindToPopups must also be checked in: + # V8FunctionHandler_Execute() and OnContextCreated(), so that calling + # a non-existent property on window object throws an error. + + if not pyFrame.IsMain() and not javascriptBindings.GetBindToFrames(): + return False + + if pyBrowser.IsPopup() and not javascriptBindings.GetBindToPopups(): + return False + + arguments = [] + iterator = v8Arguments.begin() + while iterator != v8Arguments.end(): + cefValue = deref(iterator) + arguments.append(V8ToPyValue(cefValue, v8Context)) + preinc(iterator) + + pyReturnValue = pyFunction(*arguments) + cefReturnValue.swap(PyToV8Value(pyReturnValue, v8Context)) + + return True + + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/v8function_handler_cef3.pyx b/cefpython/v8function_handler_cef3.pyx new file mode 100644 index 00000000..5ea5cf44 --- /dev/null +++ b/cefpython/v8function_handler_cef3.pyx @@ -0,0 +1,46 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef public void V8FunctionHandler_Execute( + CefRefPtr[CefBrowser] cefBrowser, + CefRefPtr[CefFrame] cefFrame, + CefString& cefFunctionName, + CefRefPtr[CefListValue] cefFunctionArguments + ) except * with gil: + cdef PyBrowser pyBrowser + cdef PyFrame pyFrame + cdef py_string functionName + cdef object function + cdef list functionArguments + cdef object returnValue + cdef py_string jsErrorMessage + try: + pyBrowser = GetPyBrowser(cefBrowser) + pyFrame = GetPyFrame(cefFrame) + functionName = CefToPyString(cefFunctionName) + Debug("V8FunctionHandler_Execute(): functionName=%s" % functionName) + jsBindings = pyBrowser.GetJavascriptBindings() + function = jsBindings.GetFunctionOrMethod(functionName) + if not function: + # The Renderer process already checks whether function + # name is valid before calling V8FunctionHandler_Execute(), + # but it is possible for the javascript bindings to change + # during execution, so it's possible for the Browser/Renderer + # bindings to be out of sync due to delay in process messaging. + jsErrorMessage = "V8FunctionHandler_Execute() FAILED: " \ + "python function not found: %s" % functionName + Debug(jsErrorMessage) + # Raise a javascript exception in that frame. + pyFrame.ExecuteJavascript("throw '%s';" % jsErrorMessage) + return + functionArguments = CefListValueToPyList(cefBrowser, + cefFunctionArguments) + returnValue = function(*functionArguments) + if returnValue != None: + Debug("V8FunctionHandler_Execute() WARNING: function returned" \ + "value, but returning values to javascript is not " \ + "supported, functionName=%s" % functionName) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/v8utils_cef1.pyx b/cefpython/v8utils_cef1.pyx new file mode 100644 index 00000000..864f5761 --- /dev/null +++ b/cefpython/v8utils_cef1.pyx @@ -0,0 +1,223 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# CefV8 Objects, Arrays and Functions can be created or modified only +# inside V8 context, you need to call CefV8Context::Enter() and +# CefV8Context::Exit(), see: +# http://code.google.com/p/chromiumembedded/issues/detail?id=203 + +cdef list CefV8StackTraceToPython(CefRefPtr[CefV8StackTrace] cefTrace): + cdef int frameNumber + cdef int frameCount = cefTrace.get().GetFrameCount() + cdef CefRefPtr[CefV8StackFrame] cefFrame + cdef CefV8StackFrame* framePtr + cdef list pyTrace = [] + + for frameNumber in range(0, frameCount): + cefFrame = cefTrace.get().GetFrame(frameNumber) + framePtr = cefFrame.get() + pyFrame = {} + pyFrame["script"] = CefToPyString(framePtr.GetScriptName()) + pyFrame["scriptOrSourceUrl"] = CefToPyString( + framePtr.GetScriptNameOrSourceURL()) + pyFrame["function"] = CefToPyString(framePtr.GetFunctionName()) + pyFrame["line"] = framePtr.GetLineNumber() + pyFrame["column"] = framePtr.GetColumn() + pyFrame["isEval"] = framePtr.IsEval() + pyFrame["isConstructor"] = framePtr.IsConstructor() + pyTrace.append(pyFrame) + + return pyTrace + +cpdef list GetJavascriptStackTrace(int frameLimit=100): + assert IsThread(TID_UI), ( + "cefpython.GetJavascriptStackTrace() may only be called on the UI thread") + cdef CefRefPtr[CefV8StackTrace] cefTrace = ( + cef_v8_stack_trace.GetCurrent(frameLimit)) + return CefV8StackTraceToPython(cefTrace) + +cpdef str FormatJavascriptStackTrace(list stackTrace): + cdef str formatted = "" + cdef dict frame + for frameNumber, frame in enumerate(stackTrace): + formatted += "\t[%s] %s() in %s on line %s (col:%s)\n" % ( + frameNumber, + frame["function"], + frame["scriptOrSourceUrl"], + frame["line"], + frame["column"]) + return formatted + +cdef object V8ToPyValue( + CefRefPtr[CefV8Value] v8Value, + CefRefPtr[CefV8Context] v8Context, + int nestingLevel=0): + + # With nestingLevel > 10 we get system exceptions. + if nestingLevel > 8: + raise Exception("V8ToPyValue() failed: data passed from Javascript to " + "Python has more than 8 levels of nesting, this is probably an infinite " + "recursion, stopping.") + + cdef CefV8Value* v8ValuePtr = v8Value.get() + cdef CefString cefString + cdef CefString cefFuncName + cdef cpp_vector[CefString] keys + cdef cpp_vector[CefString].iterator iterator + + cdef list pyArray + cdef int callbackId + cdef dict pyDict + + # A test against IsArray should be done before IsObject(). + if v8ValuePtr.IsArray(): + pyArray = [] + for key in range(0, v8ValuePtr.GetArrayLength()): + pyArray.append(V8ToPyValue( + v8ValuePtr.GetValue(int(key)), + v8Context, + nestingLevel+1)) + return pyArray + elif v8ValuePtr.IsBool(): + return v8ValuePtr.GetBoolValue() + elif v8ValuePtr.IsDate(): + # TODO: convert it to string with no error. + raise Exception("V8ToPyValue() failed: Date object is not supported, " + "you are not allowed to pass it from Javascript to Python.") + elif v8ValuePtr.IsInt(): + # A check against IsInt() must be done before IsDouble(), as any js integer + # returns true when calling IsDouble(). + return v8ValuePtr.GetIntValue() + elif v8ValuePtr.IsUInt(): + return v8ValuePtr.GetUIntValue() + elif v8ValuePtr.IsDouble(): + return v8ValuePtr.GetDoubleValue() + elif v8ValuePtr.IsFunction(): + callbackId = PutV8JavascriptCallback(v8Value, v8Context) + return JavascriptCallback(callbackId) + elif v8ValuePtr.IsNull(): + return None + elif v8ValuePtr.IsObject(): + # A test against IsObject() should be done after IsArray(). + # Remember about increasing the nestingLevel. + v8ValuePtr.GetKeys(keys) + iterator = keys.begin() + pyDict = {} + while iterator != keys.end(): + cefString = deref(iterator) + key = CefToPyString(cefString) + value = V8ToPyValue( + v8ValuePtr.GetValue(cefString), + v8Context, + nestingLevel+1) + pyDict[key] = value + preinc(iterator) + return pyDict + elif v8ValuePtr.IsString(): + return CefToPyString(v8ValuePtr.GetStringValue()) + elif v8ValuePtr.IsUndefined(): + return None + else: + raise Exception("V8ToPyValue() failed: unknown type of CefV8Value.") + +# Any function calling PyToV8Value must be inside that v8Context, +# check current context and call Enter if required otherwise exception is +# thrown while trying to create an array, object or function. + +cdef CefRefPtr[CefV8Value] PyToV8Value( + object pyValue, + CefRefPtr[CefV8Context] v8Context, + int nestingLevel=0) except *: + + # With nestingLevel > 10 we get system exceptions. + if nestingLevel > 8: + raise Exception("PyToV8Value() failed: data passed from Python " + "to Javascript has more than 8 levels of nesting, this is probably " + "an infinite recursion, stopping.") + + cdef cpp_bool sameContext + if g_debug: + sameContext = v8Context.get().IsSame(cef_v8_static.GetCurrentContext()) + if not sameContext: + raise Exception("PyToV8Value() called in wrong v8 context") + + cdef CefString cefString + cdef CefRefPtr[CefV8Value] v8Value + cdef CefString cefFuncName + cdef type pyValueType = type(pyValue) + + if pyValueType == tuple: + pyValue = list(pyValue) + + # Check type again, as code above may have changed it. + pyValueType = type(pyValue) + + cdef int index + cdef object value + cdef CefRefPtr[V8FunctionHandler] v8FunctionHandler + cdef CefRefPtr[CefV8Handler] v8Handler + cdef int callbackId + cdef object key + + if pyValueType == list: + v8Value = cef_v8_static.CreateArray(len(pyValue)) + for index,value in enumerate(pyValue): + v8Value.get().SetValue( + index, + PyToV8Value(value, v8Context, nestingLevel+1)) + return v8Value + elif pyValueType == bool: + return cef_v8_static.CreateBool(bool(pyValue)) + elif pyValueType == int: + return cef_v8_static.CreateInt(int(pyValue)) + elif pyValueType == long: + # Int32 range is -2147483648..2147483647, we've increased the + # minimum size by one as Cython was throwing a warning: + # "unary minus operator applied to unsigned type, result still + # unsigned". + if pyValue <= 2147483647 and pyValue >= -2147483647: + return cef_v8_static.CreateInt(int(pyValue)) + else: + PyToCefString(str(pyValue), cefString) + return cef_v8_static.CreateString(cefString) + elif pyValueType == float: + return cef_v8_static.CreateDouble(float(pyValue)) + elif pyValueType == types.FunctionType or pyValueType == types.MethodType: + v8FunctionHandler = new V8FunctionHandler() + v8FunctionHandler.get().SetContext(v8Context) + v8Handler = v8FunctionHandler.get() + PyToCefString(pyValue.__name__, cefFuncName) + # V8PythonCallback. + v8Value = cef_v8_static.CreateFunction(cefFuncName, v8Handler) + callbackId = PutPythonCallback(pyValue) + v8FunctionHandler.get().SetCallback_RemovePythonCallback( + RemovePythonCallback) + v8FunctionHandler.get().SetPythonCallbackID(callbackId) + return v8Value + elif pyValueType == type(None): + return cef_v8_static.CreateNull() + elif pyValueType == dict: + v8Value = cef_v8_static.CreateObject(NULL) + for key, value in pyValue.items(): + # A dict may have an int key, a string key or even a tuple key: + # {0: 12, '0': 12, (0, 1): 123} + # Remember about increasing nestingLevel. + PyToCefString(str(key), cefString) + v8Value.get().SetValue( + cefString, + PyToV8Value(value, v8Context, nestingLevel+1), + V8_PROPERTY_ATTRIBUTE_NONE) + return v8Value + elif pyValueType == bytes or pyValueType == str \ + or (PY_MAJOR_VERSION < 3 and pyValueType == unicode): + # The unicode type is not defined in Python 3. + PyToCefString(pyValue, cefString) + return cef_v8_static.CreateString(cefString) + elif pyValueType == type: + PyToCefString(str(pyValue), cefString) + return cef_v8_static.CreateString(cefString) + else: + raise Exception("PyToV8Value() failed: an unsupported python type " + "was passed from python to javascript: %s, value: %s" + % (pyValueType.__name__, pyValue)) diff --git a/cefpython/var/SaveImage.pyx b/cefpython/var/SaveImage.pyx new file mode 100644 index 00000000..ec720bb4 --- /dev/null +++ b/cefpython/var/SaveImage.pyx @@ -0,0 +1,92 @@ +# +# Browser.SaveImage() +# + +cpdef py_bool SaveImage(self, py_string filePath, + str imageType="bitmap"): + assert IsThread(TID_UI), ( + "Browser.SaveImage(): this method should only be called " + "on the UI thread") + + cdef tuple size = self.GetSize(PET_VIEW) + cdef int width, height + if size: + (width, height) = size + else: + return False + + # The charFilePath pointer is tied to the lifetime + # of the filePath string. strlen() is a C function. + cdef char* charFilePath = filePath + cdef int filePathLength = strlen(charFilePath) + cdef wchar_t* widecharFilePath = calloc( + filePathLength, wchar_t_size) + CharToWidechar(charFilePath, widecharFilePath, filePathLength) + + cdef void* bits + + cdef BITMAPINFOHEADER bitmapInfoHeader + bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER) + bitmapInfoHeader.biWidth = width + bitmapInfoHeader.biHeight = -height # minus means top-down bitmap + bitmapInfoHeader.biPlanes = 1 + bitmapInfoHeader.biBitCount = 32 + bitmapInfoHeader.biCompression = BI_RGB # no compression + bitmapInfoHeader.biSizeImage = 0 + bitmapInfoHeader.biXPelsPerMeter = 1 + bitmapInfoHeader.biYPelsPerMeter = 1 + bitmapInfoHeader.biClrUsed = 0 + bitmapInfoHeader.biClrImportant = 0 + + cdef BITMAPINFO* bitmapInfo + bitmapInfo = calloc(1, sizeof(BITMAPINFO)) + bitmapInfo.bmiHeader = bitmapInfoHeader + + cdef HDC screen_dc = GetDC(NULL) + cdef HBITMAP bitmap = CreateDIBSection( + screen_dc, bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0) + ReleaseDC(NULL, screen_dc) + + cdef PaintBuffer + + if bitmap: + # cefclient_win.cpp > UIT_RunGetImageTest + # TODO... + + free(widecharFilePath) + free(bitmapInfo) + + return True + +# +# windows.pxd: +# + + ctypedef struct BITMAPINFOHEADER: + DWORD biSize + LONG biWidth + LONG biHeight + WORD biPlanes + WORD biBitCount + DWORD biCompression + DWORD biSizeImage + LONG biXPelsPerMeter + LONG biYPelsPerMeter + DWORD biClrUsed + DWORD biClrImportant + ctypedef struct RGBQUAD: + pass + ctypedef struct BITMAPINFO: + BITMAPINFOHEADER bmiHeader + RGBQUAD bmiColors[1] + cdef DWORD BI_RGB + cdef HDC GetDC(HWND hWnd) + cdef HBITMAP CreateDIBSection( + HDC hdc, + BITMAPINFO *pbmi, + UINT iUsage, + void **ppvBits, + HANDLE hSection, + DWORD dwOffset) + cdef UINT DIB_RGB_COLORS + cdef int ReleaseDC(HWND hWnd,HDC hDC) diff --git a/cefpython/var/WideCharToPyString.pyx b/cefpython/var/WideCharToPyString.pyx new file mode 100644 index 00000000..bbf9285d --- /dev/null +++ b/cefpython/var/WideCharToPyString.pyx @@ -0,0 +1,12 @@ +from stddef cimport wchar_t + +cdef object WideCharToPyString(wchar_t *wcharstr): + cdef int charstr_bytes = WideCharToMultiByte(CP_UTF8, 0, wcharstr, -1, NULL, 0, NULL, NULL) + cdef char* charstr = calloc(charstr_bytes, sizeof(char)) + cdef int copied_bytes = WideCharToMultiByte(CP_UTF8, 0, wcharstr, -1, charstr, charstr_bytes, NULL, NULL) + if bytes == str: + pystring = "" + charstr # Python 2.7 + else: + pystring = (b"" + charstr).decode("utf-8", "ignore") # Python 3 + free(charstr) + return pystring \ No newline at end of file diff --git a/cefpython/var/_new-r750.txt b/cefpython/var/_new-r750.txt new file mode 100644 index 00000000..4129d123 --- /dev/null +++ b/cefpython/var/_new-r750.txt @@ -0,0 +1,37 @@ +JavascriptCallback.Call() - when there is a javascript exception you are +able to cancel it using ClearException(), use it in a case someone puts +.Call() inside try: catch:. + +JavascriptCallback.Call() - we are able get get stack trace of exception, +see CefV8StackTrace and CefV8StackFrame. + +- Make user data an attribute for all CefV8Value object types and not just +CreateObject ( issue #547 ). + +Move exception handling from an ExecuteFunction argument to a CefV8Value +attribute ( issue #546 ). + +Add CefV8Context::Eval method for synchronous JavaScript execution that +returns a value or exception ( issue #444 ). + +- Add CefV8Value::CreateUInt method and indicate that integer types are 32bit +via usage of int32 and uint32 types ( issue #331 ). + +Fix to mouse scrolling on second monitor. + +- Windows: Delay destroying the browser window until pending drag operations +have completed ( issue #610 ). + +Fix misspelling of the Referer HTTP header ( issue #619 ). + +Make the |target_domain| parameter to CefAddCrossOriginWhitelistEntry and +CefRemoveCrossOriginWhitelistEntry optional. + +- Add persistent HTML5 application cache support ( issue #543 ). + +Windows: Add dialog for input type="file" ( issue #632 ). + +Add new CefV8StackTrace and CefV8StackFrame interfaces to support retrieval of +the JavaScript stack trace for the currently active V8 context ( issue #682 ). + +Add the ability to customize the animation frame rate ( issue #697 ). \ No newline at end of file diff --git a/cefpython/var/_new-r909.txt b/cefpython/var/_new-r909.txt new file mode 100644 index 00000000..70860f11 --- /dev/null +++ b/cefpython/var/_new-r909.txt @@ -0,0 +1,14 @@ +Add a new CefGetGeolocation function for retrieving geolocation information via +an API callback ( issue #764 ). + +- Expose tracing functionality via new cef_trace.h and cef_trace_event.h headers +( issue #711 ). + +Add CefV8ContextHandler::OnUncaughtException callback ( issue #736 ). + +Eliminate use of scoped directories ( issue #670 ). +- related to cefpython Issue 2 - app error on exit + +Create a temporary cache_path directory if none is specified ( issue #735 ). + +Add CefZoomHandler interface to support custom zoom handling ( issue #733 ). \ No newline at end of file diff --git a/cefpython/var/_unfinished.txt b/cefpython/var/_unfinished.txt new file mode 100644 index 00000000..1bf0bbb5 --- /dev/null +++ b/cefpython/var/_unfinished.txt @@ -0,0 +1,10 @@ + +utils.pyx > GetPyBrowserByCefBrowser() > Popups: + + # Should we pass handlers from the parent? {} - empty right now. + # Add a new parameter in CreateBrowser() called "popupsInheritHandlers"? + # Or maybe just an another dict "popupHandlers"? User could pass the same + # handlers dictionary to both parameters. + + # What about popups created by popups? How do we do the inheritance in this case? + diff --git a/cefpython/var/about.txt b/cefpython/var/about.txt new file mode 100644 index 00000000..92da004a --- /dev/null +++ b/cefpython/var/about.txt @@ -0,0 +1,16 @@ +CefPython - python bindings for the Chromium Embedded Framework. + +License + New BSD License +Copyright + Czarek Tomczak. All rights reserved. +Website: + http://code.google.com/p/cefpython/ + +-- + +There are a few ways to make bindings to CEF: +1) ctypes (only C api from DLLs) +2) cython +3) Boost.Python +4) others: http://wiki.cython.org/WrappingCorCpp diff --git a/cefpython/var/c callback.pyx b/cefpython/var/c callback.pyx new file mode 100644 index 00000000..7831abd1 --- /dev/null +++ b/cefpython/var/c callback.pyx @@ -0,0 +1,74 @@ +""" +setup.bat: +----------- +del cheese.pyd +call python "setup.py" build_ext --inplace +pause + +run_cheese.py: +----------------- +import cheese +cheese.find() + +setup.py: +----------- +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + +setup( + name = 'callback', + ext_modules=[ + Extension("cheese", ["cheese.pyx"]), + ], + cmdclass = {'build_ext': build_ext} +) + +""" + +""" +cheese.pyx: +-------------- +""" + +# It can get even easier "Using Cython Declarations from C": +# http://docs.cython.org/src/userguide/external_C_code.html#using-cython-declarations-from-c + +cdef extern from "cheesefinder.h": + ctypedef int (*cheesefunc)(char *name) + void find_cheeses(cheesefunc user_func) + +def find(): + find_cheeses(report_cheese) + +# When using callbacks from C need to use GIL: +# http://docs.cython.org/src/userguide/external_C_code.html#acquiring-and-releasing-the-gil + +cdef int report_cheese(char* name) with gil: + print("Found cheese: " + name) + return 0 + +""" +cheesefinder.h: +------------------ + +typedef int (*cheesefunc)(char *name); +void find_cheeses(cheesefunc user_func); + +static char *cheeses[] = { + "cheddar", + "camembert", + "that runny one", + 0 +}; + +void find_cheeses(cheesefunc user_func) { + char **p = cheeses; + int r = 1; + while (r && *p) { + r = user_func(*p); + ++p; + } +} + +""" \ No newline at end of file diff --git a/cefpython/var/cef-build-steps.txt b/cefpython/var/cef-build-steps.txt new file mode 100644 index 00000000..38861279 --- /dev/null +++ b/cefpython/var/cef-build-steps.txt @@ -0,0 +1,43 @@ +http://www.chromium.org/developers/how-tos/build-instructions-windows +http://code.google.com/p/chromiumembedded/wiki/BranchesAndBuilding + +1. +cd e:\chromium\ +gclient config http://src.chromium.org/svn/releases/18.0.1025.166 + +2. +edit .gclient file: +"custom_deps" : { + "src/third_party/WebKit/LayoutTests": None, + "src/chrome/tools/test/reference_build/chrome_win": None, + "src/chrome_frame/tools/test/reference_build/chrome_win": None, + "src/chrome/tools/test/reference_build/chrome_linux": None, + "src/chrome/tools/test/reference_build/chrome_mac": None, + "src/third_party/hunspell_dictionaries": None + }, + +3. +cd e:\chromium\ +gclient sync --jobs 8 --force + +4. +cd e:\chromium\src\ + +Branch 1025: +svn checkout -r 607 http://chromiumembedded.googlecode.com/svn/branches/1025/ cef +svn checkout -r 750 http://chromiumembedded.googlecode.com/svn/branches/1025/ cef + +Branch 1180: +http://src.chromium.org/svn/releases/21.0.1180.18 +svn checkout -r 750 http://chromiumembedded.googlecode.com/svn/branches/1180/cef1/ cef + +5. +Create GYP_MSVS_VERSION environment variable and put version of VS you use: 2008 or 2010 + +cd e:\chromium\src\cef +cef_create_projects.bat + +6. +Open src\cef\cef.sln +Change to "Release". +Build. \ No newline at end of file diff --git a/cefpython/var/cef_check_style.bat b/cefpython/var/cef_check_style.bat new file mode 100644 index 00000000..a8d070b7 --- /dev/null +++ b/cefpython/var/cef_check_style.bat @@ -0,0 +1,2 @@ +cd C:\cef1_trunk\src\cef\tools\ +start check_style.bat --filter=-readability/todo,-runtime/references,-runtime/explicit,-whitespace/labels,-readability/casting,-runtime/sizeof,-runtime/int ../libcef/cef_process_ui_thread.cc ../include/internal/cef_types.h ../include/internal/cef_types_wrappers.h ../tests/cefclient/cefclient_switches.h ../tests/cefclient/cefclient_switches.cpp ../tests/cefclient/cefclient.cpp ../tests/unittests/test_suite.cc \ No newline at end of file diff --git a/cefpython/var/cef_unittests_dcheck.bat b/cefpython/var/cef_unittests_dcheck.bat new file mode 100644 index 00000000..0eb4ac1d --- /dev/null +++ b/cefpython/var/cef_unittests_dcheck.bat @@ -0,0 +1,2 @@ +cef_unittests.exe -release-dcheck-enabled -log-severity=verbose +pause \ No newline at end of file diff --git a/cefpython/var/cefclient_dcheck.bat b/cefpython/var/cefclient_dcheck.bat new file mode 100644 index 00000000..0c23b8d5 --- /dev/null +++ b/cefpython/var/cefclient_dcheck.bat @@ -0,0 +1,2 @@ +cefclient.exe -release-dcheck-enabled -log-severity=verbose +pause \ No newline at end of file diff --git a/cefpython/var/cefwxpanel_sample2.png b/cefpython/var/cefwxpanel_sample2.png new file mode 100644 index 00000000..9639cf9f Binary files /dev/null and b/cefpython/var/cefwxpanel_sample2.png differ diff --git a/cefpython/var/compiling_chromium.txt b/cefpython/var/compiling_chromium.txt new file mode 100644 index 00000000..00536c15 --- /dev/null +++ b/cefpython/var/compiling_chromium.txt @@ -0,0 +1,5 @@ +1. Enable dchecks in release mode: + http://code.google.com/p/chromiumembedded/issues/detail?id=790 + cef_process_ui_thread.cc >> CefProcessUIThread::Init(): + logging_dest = logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG + logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS \ No newline at end of file diff --git a/cefpython/var/cyan_new_logo.png b/cefpython/var/cyan_new_logo.png new file mode 100644 index 00000000..29772f8e Binary files /dev/null and b/cefpython/var/cyan_new_logo.png differ diff --git a/cefpython/var/dpi-aware.png b/cefpython/var/dpi-aware.png new file mode 100644 index 00000000..4df24081 Binary files /dev/null and b/cefpython/var/dpi-aware.png differ diff --git a/cefpython/var/envpath.bat b/cefpython/var/envpath.bat new file mode 100644 index 00000000..eff6d0a2 --- /dev/null +++ b/cefpython/var/envpath.bat @@ -0,0 +1,2 @@ +@echo %PATH% +pause \ No newline at end of file diff --git a/cefpython/var/envpath_broadcast.py b/cefpython/var/envpath_broadcast.py new file mode 100644 index 00000000..2330a1c7 --- /dev/null +++ b/cefpython/var/envpath_broadcast.py @@ -0,0 +1,6 @@ +import win32api +import win32con + +# http://stackoverflow.com/questions/531998/is-there-a-way-to-set-the-environment-path-programatically-in-c-on-windows +win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, "Environment") +print("WM_SETTINGCHANGE \"Environment\" broadcasted to all windows.") diff --git a/cefpython/var/envpath_py27_32bit.bat b/cefpython/var/envpath_py27_32bit.bat new file mode 100644 index 00000000..23ac7f07 --- /dev/null +++ b/cefpython/var/envpath_py27_32bit.bat @@ -0,0 +1,24 @@ +@echo off + +@REM # So that replacement on string can be done. +SETLOCAL EnableDelayedExpansion + +@echo Current PATH: %PATH% +@echo. + +SET newpath=%PATH:python32=python27% +SET newpath=%newpath:_64bit=_32bit% + +@echo New PATH: +@echo %newpath% + +@REM # http://stackoverflow.com/questions/531998/is-there-a-way-to-set-the-environment-path-programatically-in-c-on-windows +REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%newpath%" /f + +CALL python %~dp0envpath_broadcast.py + +@REM # %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python27 +@REM # C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python32 + +@echo. +PAUSE diff --git a/cefpython/var/envpath_py27_64bit.bat b/cefpython/var/envpath_py27_64bit.bat new file mode 100644 index 00000000..bf65db5d --- /dev/null +++ b/cefpython/var/envpath_py27_64bit.bat @@ -0,0 +1,24 @@ +@echo off + +@REM # So that replacement on string can be done. +SETLOCAL EnableDelayedExpansion + +@echo Current PATH: %PATH% +@echo. + +SET newpath=%PATH:python32=python27% +SET newpath=%newpath:_32bit=_64bit% + +@echo New PATH: +@echo %newpath% + +@REM # http://stackoverflow.com/questions/531998/is-there-a-way-to-set-the-environment-path-programatically-in-c-on-windows +REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%newpath%" /f + +CALL python %~dp0envpath_broadcast.py + +@REM # %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python27 +@REM # C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python32 + +@echo. +PAUSE diff --git a/cefpython/var/envpath_py32_32bit.bat b/cefpython/var/envpath_py32_32bit.bat new file mode 100644 index 00000000..f05b6513 --- /dev/null +++ b/cefpython/var/envpath_py32_32bit.bat @@ -0,0 +1,24 @@ +@echo off + +@REM # So that replacement on string can be done. +SETLOCAL EnableDelayedExpansion + +@echo Current PATH: %PATH% +@echo. + +SET newpath=%PATH:python27=python32% +SET newpath=%newpath:_64bit=_32bit% + +@echo New PATH: +@echo %newpath% + +@REM # http://stackoverflow.com/questions/531998/is-there-a-way-to-set-the-environment-path-programatically-in-c-on-windows +REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%newpath%" /f + +CALL python %~dp0envpath_broadcast.py + +@REM # %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python27 +@REM # C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python32 + +@echo. +PAUSE diff --git a/cefpython/var/envpath_py32_64bit.bat b/cefpython/var/envpath_py32_64bit.bat new file mode 100644 index 00000000..7fb41a2f --- /dev/null +++ b/cefpython/var/envpath_py32_64bit.bat @@ -0,0 +1,24 @@ +@echo off + +@REM # So that replacement on string can be done. +SETLOCAL EnableDelayedExpansion + +@echo Current PATH: %PATH% +@echo. + +SET newpath=%PATH:python27=python32% +SET newpath=%newpath:_32bit=_64bit% + +@echo New PATH: +@echo %newpath% + +@REM # http://stackoverflow.com/questions/531998/is-there-a-way-to-set-the-environment-path-programatically-in-c-on-windows +REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%newpath%" /f + +CALL python %~dp0envpath_broadcast.py + +@REM # %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python27 +@REM # C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Documents and Settings\Admin\Dane aplikacji\npm;C:\Program Files\nodejs\;D:\bin;D:\bin\python32 + +@echo. +PAUSE diff --git a/cefpython/var/fullscreen.py b/cefpython/var/fullscreen.py new file mode 100644 index 00000000..aafb15f8 --- /dev/null +++ b/cefpython/var/fullscreen.py @@ -0,0 +1,41 @@ +if platform.system() == "Windows": + for_metro = False + hwnd = browser.GetWindowID() + # Logic copied from chromium > fullscreen_handler.cc > FullscreenHandler::SetFullscreenImpl: + # http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc + if not browser.GetUserData("is_fullscreen"): + browser.SetUserData("SavedWindowInfo_maximized", ctypes.windll.user32.IsZoomed(hwnd)) + if browser.GetUserData("SavedWindowInfo_maximized"): + win32api.SendMessage(hwnd, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0) + browser.SetUserData("SavedWindowInfo_gwl_style", win32api.GetWindowLong(hwnd, win32con.GWL_STYLE)) + browser.SetUserData("SavedWindowInfo_gwl_exstyle", win32api.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)) + browser.SetUserData("SavedWindowInfo_window_rect", win32gui.GetWindowRect(hwnd)) + + if not browser.GetUserData("is_fullscreen"): + gwl_style = browser.GetUserData("SavedWindowInfo_gwl_style") + gwl_exstyle = browser.GetUserData("SavedWindowInfo_gwl_exstyle") + remove_style = win32con.WS_CAPTION | win32con.WS_THICKFRAME + remove_exstyle = win32con.WS_EX_DLGMODALFRAME | win32con.WS_EX_WINDOWEDGE + remove_exstyle += win32con.WS_EX_CLIENTEDGE | win32con.WS_EX_STATICEDGE + win32api.SetWindowLong(hwnd, win32con.GWL_STYLE, gwl_style & ~(remove_style)) + win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, gwl_exstyle & ~(remove_exstyle)) + if not for_metro: + # MONITOR_DEFAULTTONULL, MONITOR_DEFAULTTOPRIMARY, MONITOR_DEFAULTTONEAREST + monitor = win32api.MonitorFromWindow(hwnd, win32con.MONITOR_DEFAULTTONEAREST) + monitorInfo = win32api.GetMonitorInfo(monitor) # keys: Device, Work, Monitor + (left, top, right, bottom) = monitorInfo["Monitor"] + win32gui.SetWindowPos(hwnd, None, left, top, right-left, bottom-top, + win32con.SWP_NOZORDER | win32con.SWP_NOACTIVATE | win32con.SWP_FRAMECHANGED) + else: + gwl_style = browser.GetUserData("SavedWindowInfo_gwl_style") + gwl_exstyle = browser.GetUserData("SavedWindowInfo_gwl_exstyle") + win32api.SetWindowLong(hwnd, win32con.GWL_STYLE, gwl_style) + win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, gwl_exstyle) + if not for_metro: + (left, top, right, bottom) = browser.GetUserData("SavedWindowInfo_window_rect") + win32gui.SetWindowPos(hwnd, None, left, top, right-left, bottom-top, + win32con.SWP_NOZORDER | win32con.SWP_NOACTIVATE | win32con.SWP_FRAMECHANGED) + if browser.GetUserData("SavedWindowInfo_maximized"): + win32api.SendMessage(hwnd, win32con.WM_SYSCOMMAND, win32con.SC_MAXIMIZE, 0) + + browser.SetUserData("is_fullscreen", not bool(browser.GetUserData("is_fullscreen"))) \ No newline at end of file diff --git a/cefpython/var/gtk-embedding-example.txt b/cefpython/var/gtk-embedding-example.txt new file mode 100644 index 00000000..e8ae0954 --- /dev/null +++ b/cefpython/var/gtk-embedding-example.txt @@ -0,0 +1,184 @@ +From here: +http://www.daa.com.au/pipermail/pygtk/2005-June/010461.html +(google cache) + +--------------------------------------------------------------------------------------------------------- + +To jest kopia z pamięci podręcznej Google adresu http://www.daa.com.au/pipermail/pygtk/2005-June/010461.html. Zdjęcie przedstawia stan strony z 4 Sie 2012 16:58:27 GMT. Aktualna strona może wyglądać inaczej. Więcej informacji +Wskazówka: aby szybko znaleźć wyszukiwane hasło na stronie, naciśnij Ctrl+F lub ⌘-F (Mac) i użyj paska wyszukiwania. + +Wersja tekstowa + +[pygtk] Embedding a Win32 window or ActiveX control in a pygtk application + +Richie Hindle richie at entrian.com +Thu Jun 9 07:23:41 WST 2005 +Previous message: [pygtk] Embedding a Win32 window or ActiveX control in a pygtk application +Next message: [pygtk] Embedding a Win32 window or ActiveX control in a pygtk application +Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] +[Guillaume] +> I don't remember all details but I did embed a Flash file into a GTK +> window some time ago: +> [...] +> axcontainer=gtk.DrawingArea() + +Aha! Parenting the control to a DrawingArea was the step I was missing. +Thanks! + +I've now got this working, and an example application (a poor man's webbrowser, +embedding IE in pygtk via AtlAxWin and ctypes) is below. There are a few things +I couldn't make work: + + o My keyboard accelerator (Alt+A to focus the address box) doesn't work + when IE has the focus. Any ideas? How do pygtk accelerators work under the + surface? + + o Clicking a Gtk control when the IE control has the focus doesn't focus + the Gtk control. I worked around this by putting an event handler on the + Gtk controls for "button-press-event", but it would need to be done for + every Gtk control - is there a better solution? + + o IE's accelerator keys (eg. Tab and Alt+Left) don't work. In a pure Win32 + app, I'd fix this by calling IOleInPlaceActiveObject::TranslateAccelerator() + in the message pump, but can I get access to the message pump in pygtk? + + o Pressing Enter in the address box should have the same effect as pressing + the Go button - I've done this, but it's a hack. Is there a better way? + + o I'm using 65293 as the code for the Enter key - does pygtk have a constant + for this? + +This is my first pygtk program, so any criticism or suggestions will be +gratefully received! + +-------------------------------- snip snip -------------------------------- + +"""A poor man's webbrowser, embedding IE in pygtk via AtlAxWin and ctypes.""" + +import win32con + +from ctypes import * +from ctypes.wintypes import * +from ctypes.com import IUnknown +from ctypes.com.automation import IDispatch, VARIANT +from ie6_gen import IWebBrowser2 # Copy ie6_gen from ctypes\win32\com\samples +kernel32 = windll.kernel32 +user32 = windll.user32 +atl = windll.atl # If this fails, you need atl.dll + +import pygtk +pygtk.require("2.0") +import gtk + +class GUI: + def __init__(self): + # Create the main GTK window. + self.main = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.main.set_title("Poor man's browser [TM]") + self.main.connect("destroy", gtk.main_quit) + self.main.set_size_request(750, 550) + self.main.realize() + + # Create a VBox to house the address bar and the IE control. + self.mainVBox = gtk.VBox() + self.main.add(self.mainVBox) + self.mainVBox.show() + + # Create the address bar. + self.addressEntry = gtk.Entry() + self.addressEntry.show() + self.addressEntry.connect("key-press-event", self.on_addressEntry_key) + self.addressLabel = gtk.Label() + self.addressLabel.set_text_with_mnemonic("_Address: ") + self.addressLabel.set_mnemonic_widget(self.addressEntry) + self.addressLabel.show() + self.goButton = gtk.Button(" Go ") + self.goButton.show() + self.goButton.connect("clicked", self.on_goButton_clicked) + self.addressHbox = gtk.HBox() + self.addressHbox.show() + self.addressHbox.add(self.addressLabel) + self.addressHbox.add(self.addressEntry) + self.addressHbox.add(self.goButton) + self.addressHbox.set_child_packing(self.addressLabel, + False, True, 2, gtk.PACK_START) + self.addressHbox.set_child_packing(self.goButton, + False, True, 0, gtk.PACK_END) + self.mainVBox.add(self.addressHbox) + self.mainVBox.set_child_packing(self.addressHbox, + False, True, 0, gtk.PACK_START) + + # Create a DrawingArea to host IE and add it to the hbox. + self.container = gtk.DrawingArea() + self.mainVBox.add(self.container) + self.container.show() + + # Make the container accept the focus and pass it to the control; + # this makes the Tab key pass focus to IE correctly. + self.container.set_property("can-focus", True) + self.container.connect("focus", self.on_container_focus) + + # Resize the AtlAxWin window with its container. + self.container.connect("size-allocate", self.on_container_size) + + # Create an instance of IE via AtlAxWin. + atl.AtlAxWinInit() + hInstance = kernel32.GetModuleHandleA(None) + parentHwnd = self.container.window.handle + self.atlAxWinHwnd = \ + user32.CreateWindowExA(0, "AtlAxWin", "http://www.pygtk.org", + win32con.WS_VISIBLE | win32con.WS_CHILD | + win32con.WS_HSCROLL | win32con.WS_VSCROLL, + 0, 0, 100, 100, parentHwnd, None, hInstance, 0) + + # Get the IWebBrowser2 interface for the IE control. + pBrowserUnk = POINTER(IUnknown)() + atl.AtlAxGetControl(self.atlAxWinHwnd, byref(pBrowserUnk)) + self.pBrowser = POINTER(IWebBrowser2)() + pBrowserUnk.QueryInterface(byref(IWebBrowser2._iid_), + byref(self.pBrowser)) + + # Create a Gtk window that refers to the native AtlAxWin window. + self.gtkAtlAxWin = gtk.gdk.window_foreign_new(long(self.atlAxWinHwnd)) + + # By default, clicking a GTK widget doesn't grab the focus away from + # a native Win32 control. + self.addressEntry.connect("button-press-event", self.on_widget_click) + + def on_goButton_clicked(self, widget): + v = byref(VARIANT()) + self.pBrowser.Navigate(self.addressEntry.get_text(), v, v, v, v) + + def on_addressEntry_key(self, widget, event): + if event.keyval == 65293: # "Enter"; is there a constant for this? + self.on_goButton_clicked(None) + + def on_widget_click(self, widget, data): + self.main.window.focus() + + def on_container_size(self, widget, sizeAlloc): + self.gtkAtlAxWin.move_resize(0, 0, sizeAlloc.width, sizeAlloc.height) + + def on_container_focus(self, widget, data): + # Pass the focus to IE. First get the HWND of the IE control; this + # is a bit of a hack but I couldn't make IWebBrowser2._get_HWND work. + rect = RECT() + user32.GetWindowRect(self.atlAxWinHwnd, byref(rect)) + ieHwnd = user32.WindowFromPoint(POINT(rect.left, rect.top)) + user32.SetFocus(ieHwnd) + +# Show the main window and run the message loop. +gui = GUI() +gui.main.show() +gtk.main() + +-------------------------------- snip snip -------------------------------- + +-- +Richie Hindle +richie at entrian.com + +Previous message: [pygtk] Embedding a Win32 window or ActiveX control in a pygtk application +Next message: [pygtk] Embedding a Win32 window or ActiveX control in a pygtk application +Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] +More information about the pygtk mailing list \ No newline at end of file diff --git a/cefpython/var/http_authentication.php b/cefpython/var/http_authentication.php new file mode 100644 index 00000000..bd563a43 --- /dev/null +++ b/cefpython/var/http_authentication.php @@ -0,0 +1,30 @@ +"; + print "Username=$username
"; + print "Password=$password
"; + + } +} + +?> \ No newline at end of file diff --git a/cefpython/var/icon48.png b/cefpython/var/icon48.png new file mode 100644 index 00000000..df65e597 Binary files /dev/null and b/cefpython/var/icon48.png differ diff --git a/cefpython/var/kivy-screenshot.png b/cefpython/var/kivy-screenshot.png new file mode 100644 index 00000000..ec009803 Binary files /dev/null and b/cefpython/var/kivy-screenshot.png differ diff --git a/cefpython/var/linux/linux.txt b/cefpython/var/linux/linux.txt new file mode 100644 index 00000000..cb95d23f --- /dev/null +++ b/cefpython/var/linux/linux.txt @@ -0,0 +1,26 @@ +Getting chromium sources +------------------------ +gclient sync fails, you need to install: + sudo apt-get install libdbus-glib-1-dev + +Building +-------- +building in release mode: + # j = jobs + make BUILDTYPE=Release -j4 cefclient + +Binary package +-------------- +cd /path/to/chromium/src/cef/tools +make_distrib.sh --allow-partial +If the process succeeds a binary distribution package +will be created in the /path/to/chromium/src/cef/binary_distrib directory. + +Commands +-------- +schroot -c precise32 # change chroot to precise32 +sudo schroot -a -e # -end -all chroots & sessions +schroot -l # list all chroots + +chromium/install-chroot.sh + echo "-c always copy 64bit helper binaries to 32bit chroot" \ No newline at end of file diff --git a/cefpython/var/linux/nano.txt b/cefpython/var/linux/nano.txt new file mode 100644 index 00000000..00069279 --- /dev/null +++ b/cefpython/var/linux/nano.txt @@ -0,0 +1,10 @@ +copy/paste: + Select: ALT + M + A + Copy: ALT + 6 + Paste: CTRL + U + +MC: + Zawsze mozesz uzywac wbudowanego edytora ala nortonowskiego + wtedy F3 mark + F5 copy + F2 save itp \ No newline at end of file diff --git a/cefpython/var/linux/start-env.sh b/cefpython/var/linux/start-env.sh new file mode 100755 index 00000000..f0084bf7 --- /dev/null +++ b/cefpython/var/linux/start-env.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +echo "Adding depot_tools to PATH" +export PATH="$PATH":`pwd`/depot_tools + +echo "Switching chroot to Precise32 (Ubuntu 12.04 LTS 32 bit)" +precise32 + diff --git a/cefpython/var/malloc.pyx b/cefpython/var/malloc.pyx new file mode 100644 index 00000000..96a2eb24 --- /dev/null +++ b/cefpython/var/malloc.pyx @@ -0,0 +1,4 @@ +from libc.stdlib cimport malloc, free + +cdef RECT* rect2 = malloc(sizeof(RECT)) +free(rect2) \ No newline at end of file diff --git a/cefpython/var/panda3d.png b/cefpython/var/panda3d.png new file mode 100644 index 00000000..e2e47bce Binary files /dev/null and b/cefpython/var/panda3d.png differ diff --git a/cefpython/var/pygtk.png b/cefpython/var/pygtk.png new file mode 100644 index 00000000..137700d3 Binary files /dev/null and b/cefpython/var/pygtk.png differ diff --git a/cefpython/var/pyinstaller.bat b/cefpython/var/pyinstaller.bat new file mode 100644 index 00000000..af36d918 --- /dev/null +++ b/cefpython/var/pyinstaller.bat @@ -0,0 +1,2 @@ +python D:/python/pyinstaller-2.0/pyinstaller.py --onedir --console cefadvanced.py +pause \ No newline at end of file diff --git a/cefpython/var/pyqt.png b/cefpython/var/pyqt.png new file mode 100644 index 00000000..2686bd1c Binary files /dev/null and b/cefpython/var/pyqt.png differ diff --git a/cefpython/var/pyside.png b/cefpython/var/pyside.png new file mode 100644 index 00000000..bd92efc0 Binary files /dev/null and b/cefpython/var/pyside.png differ diff --git a/cefpython/var/stdint.h b/cefpython/var/stdint.h new file mode 100644 index 00000000..d02608a5 --- /dev/null +++ b/cefpython/var/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/cefpython/var/stdint.pxd b/cefpython/var/stdint.pxd new file mode 100644 index 00000000..3984901f --- /dev/null +++ b/cefpython/var/stdint.pxd @@ -0,0 +1,108 @@ +# from stdint cimport int32_t as __int32 +# stdint.h is missing in visual studio + +# Longness only used for type promotion. +# Actual compile time size used for conversions. + +# 7.18 Integer types +cdef extern from "stdint.h" nogil: + + # 7.18.1 Integer types + # 7.18.1.1 Exact-width integer types + ctypedef signed char int8_t + ctypedef signed short int16_t + ctypedef signed int int32_t + ctypedef signed long int64_t + ctypedef unsigned char uint8_t + ctypedef unsigned short uint16_t + ctypedef unsigned int uint32_t + ctypedef unsigned long uint64_t + # 7.18.1.2 Minimum-width integer types + ctypedef signed char int_least8_t + ctypedef signed short int_least16_t + ctypedef signed int int_least32_t + ctypedef signed long int_least64_t + ctypedef unsigned char uint_least8_t + ctypedef unsigned short uint_least16_t + ctypedef unsigned int uint_least32_t + ctypedef unsigned long uint_least64_t + # 7.18.1.3 Fastest minimum-width integer types + ctypedef signed char int_fast8_t + ctypedef signed short int_fast16_t + ctypedef signed int int_fast32_t + ctypedef signed long int_fast64_t + ctypedef unsigned char uint_fast8_t + ctypedef unsigned short uint_fast16_t + ctypedef unsigned int uint_fast32_t + ctypedef unsigned long uint_fast64_t + # 7.18.1.4 Integer types capable of holding object pointers + ctypedef ssize_t intptr_t + ctypedef size_t uintptr_t + # 7.18.1.5 Greatest-width integer types + ctypedef signed long long intmax_t + ctypedef unsigned long long uintmax_t + + # 7.18.2 Limits of specified-width integer types + # 7.18.2.1 Limits of exact-width integer types + int8_t INT8_MIN + int16_t INT16_MIN + int32_t INT32_MIN + int64_t INT64_MIN + int8_t INT8_MAX + int16_t INT16_MAX + int32_t INT32_MAX + int64_t INT64_MAX + uint8_t UINT8_MAX + uint16_t UINT16_MAX + uint32_t UINT32_MAX + uint64_t UINT64_MAX + #7.18.2.2 Limits of minimum-width integer types + int_least8_t INT_LEAST8_MIN + int_least16_t INT_LEAST16_MIN + int_least32_t INT_LEAST32_MIN + int_least64_t INT_LEAST64_MIN + int_least8_t INT_LEAST8_MAX + int_least16_t INT_LEAST16_MAX + int_least32_t INT_LEAST32_MAX + int_least64_t INT_LEAST64_MAX + uint_least8_t UINT_LEAST8_MAX + uint_least16_t UINT_LEAST16_MAX + uint_least32_t UINT_LEAST32_MAX + uint_least64_t UINT_LEAST64_MAX + #7.18.2.3 Limits of fastest minimum-width integer types + int_fast8_t INT_FAST8_MIN + int_fast16_t INT_FAST16_MIN + int_fast32_t INT_FAST32_MIN + int_fast64_t INT_FAST64_MIN + int_fast8_t INT_FAST8_MAX + int_fast16_t INT_FAST16_MAX + int_fast32_t INT_FAST32_MAX + int_fast64_t INT_FAST64_MAX + uint_fast8_t UINT_FAST8_MAX + uint_fast16_t UINT_FAST16_MAX + uint_fast32_t UINT_FAST32_MAX + uint_fast64_t UINT_FAST64_MAX + #7.18.2.4 Limits of integer types capable of holding object pointers + enum: INTPTR_MIN + enum: INTPTR_MAX + enum: UINTPTR_MAX + # 7.18.2.5 Limits of greatest-width integer types + enum: INTMAX_MAX + enum: INTMAX_MIN + enum: UINTMAX_MAX + + # 7.18.3 Limits of other integer types + # ptrdiff_t + enum: PTRDIFF_MIN + enum: PTRDIFF_MAX + # sig_atomic_t + enum: SIG_ATOMIC_MIN + enum: SIG_ATOMIC_MAX + # size_t + size_t SIZE_MAX + # wchar_t + enum: WCHAR_MIN + enum: WCHAR_MAX + # wint_t + enum: WINT_MIN + enum: WINT_MAX diff --git a/cefpython/var/wxpython.png b/cefpython/var/wxpython.png new file mode 100644 index 00000000..ddaf4ce3 Binary files /dev/null and b/cefpython/var/wxpython.png differ diff --git a/cefpython/virtual_keys.pyx b/cefpython/virtual_keys.pyx new file mode 100644 index 00000000..99a6d4b0 --- /dev/null +++ b/cefpython/virtual_keys.pyx @@ -0,0 +1,190 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# Regular expression to transform these constants to a form +# that can be later pasted to wiki page: +# (http://code.google.com/p/cefpython/wiki/VirtualKey) +# +# Find what: (VK_\w+) = \w+[ ]*([^\r\n]*) +# Replace with: cefpython.`\1` \2
+ +VK_0 = 0x30 +VK_1 = 0x31 +VK_2 = 0x32 +VK_3 = 0x33 +VK_4 = 0x34 +VK_5 = 0x35 +VK_6 = 0x36 +VK_7 = 0x37 +VK_8 = 0x38 +VK_9 = 0x39 + +VK_A = 0x041 +VK_B = 0x042 +VK_C = 0x043 +VK_D = 0x044 +VK_E = 0x045 +VK_F = 0x046 +VK_G = 0x047 +VK_H = 0x048 +VK_I = 0x049 +VK_J = 0x04A +VK_K = 0x04B +VK_L = 0x04C +VK_M = 0x04D +VK_N = 0x04E +VK_O = 0x04F +VK_P = 0x050 +VK_Q = 0x051 +VK_R = 0x052 +VK_S = 0x053 +VK_T = 0x054 +VK_U = 0x055 +VK_V = 0x056 +VK_W = 0x057 +VK_X = 0x058 +VK_Y = 0x059 +VK_Z = 0x05A + +VK_F1 = 0x70 +VK_F2 = 0x71 +VK_F3 = 0x72 +VK_F4 = 0x73 +VK_F5 = 0x74 +VK_F6 = 0x75 +VK_F7 = 0x76 +VK_F8 = 0x77 +VK_F9 = 0x78 +VK_F10 = 0x79 +VK_F11 = 0x7A +VK_F12 = 0x7B +VK_F13 = 0x7C +VK_F14 = 0x7D +VK_F15 = 0x7E +VK_F16 = 0x7F +VK_F17 = 0x80 +VK_F18 = 0x81 +VK_F19 = 0x82 +VK_F20 = 0x83 +VK_F21 = 0x84 +VK_F22 = 0x85 +VK_F23 = 0x86 +VK_F24 = 0x87 + +VK_LEFT = 0x25 # Left arrow key +VK_UP = 0x26 # Up arrow key +VK_RIGHT = 0x27 # Right arrow key +VK_DOWN = 0x28 # Down arrow key + +VK_LSHIFT = 0xA0 # Left shift +VK_RSHIFT = 0xA1 # Right shift +VK_LCONTROL = 0xA2 # Left Ctrl +VK_RCONTROL = 0xA3 # Right Ctrl +VK_LMENU = 0xA4 # Left Alt +VK_RMENU = 0xA5 # Right Alt +VK_LALT = VK_LMENU +VK_RALT = VK_RMENU + +VK_BACK = 0x08 # Backspace key +VK_RETURN = 0x0D # Enter key +VK_TAB = 0x09 +VK_SPACE = 0x20 # Space bar key +VK_ESCAPE = 0x1B + +VK_SHIFT = 0x10 # Shift key +VK_CONTROL = 0x11 # Ctrl key +VK_MENU = 0x12 # Alt key +VK_LWIN = 0x5B # Left Windows key +VK_RWIN = 0x5C # Right Windows key +VK_CAPITAL = 0x14 # Caps Lock key +VK_CAPSLOCK = VK_CAPITAL + +VK_PRIOR = 0x21 # Page up +VK_NEXT = 0x22 # Page down +VK_PAGEUP = VK_PRIOR +VK_PAGEDOWN = VK_NEXT +VK_END = 0x23 +VK_HOME = 0x24 +VK_INSERT = 0x2D +VK_DELETE = 0x2E + +VK_NUMLOCK = 0x90 +VK_SCROLL = 0x91 # Scroll Lock key + +VK_SELECT = 0x29 +VK_PRINT = 0x2A +VK_EXECUTE = 0x2B +VK_SNAPSHOT = 0x2C # Print Screen key +VK_PRINTSCREEN = VK_SNAPSHOT +VK_HELP = 0x2F +VK_PAUSE = 0x13 +VK_CLEAR = 0x0C +VK_APPS = 0x5D # Applications key (Natural keyboard) +VK_SLEEP = 0x5F # Computer Sleep key + +VK_NUMPAD0 = 0x60 # Numeric keypad 0 key +VK_NUMPAD1 = 0x61 # Numeric keypad 1 key +VK_NUMPAD2 = 0x62 # Numeric keypad 2 key +VK_NUMPAD3 = 0x63 # Numeric keypad 3 key +VK_NUMPAD4 = 0x64 # Numeric keypad 4 key +VK_NUMPAD5 = 0x65 # Numeric keypad 5 key +VK_NUMPAD6 = 0x66 # Numeric keypad 6 key +VK_NUMPAD7 = 0x67 # Numeric keypad 7 key +VK_NUMPAD8 = 0x68 # Numeric keypad 8 key +VK_NUMPAD9 = 0x69 # Numeric keypad 9 key + +VK_BROWSER_BACK = 0xA6 +VK_BROWSER_FORWARD = 0xA7 +VK_BROWSER_REFRESH = 0xA8 +VK_BROWSER_STOP = 0xA9 +VK_BROWSER_SEARCH = 0xAA +VK_BROWSER_FAVORITES = 0xAB +VK_BROWSER_HOME = 0xAC + +VK_PLAY = 0xFA +VK_ZOOM = 0xFB + +VK_VOLUME_MUTE = 0xAD +VK_VOLUME_DOWN = 0xAE +VK_VOLUME_UP = 0xAF +VK_MEDIA_NEXT_TRACK = 0xB0 +VK_MEDIA_PREV_TRACK = 0xB1 +VK_MEDIA_STOP = 0xB2 +VK_MEDIA_PLAY_PAUSE = 0xB3 +VK_LAUNCH_MAIL = 0xB4 +VK_LAUNCH_MEDIA_SELECT = 0xB5 +VK_LAUNCH_APP1 = 0xB6 # Start Application 1 key +VK_LAUNCH_APP2 = 0xB7 # Start Application 2 key + +VK_MULTIPLY = 0x6A +VK_ADD = 0x6B +VK_SEPARATOR = 0x6C +VK_SUBTRACT = 0x6D +VK_DECIMAL = 0x6E +VK_DIVIDE = 0x6F + +VK_LBUTTON = 0x01 # Left mouse button +VK_RBUTTON = 0x02 # Right mouse button +VK_CANCEL = 0x03 # Control-break processing +VK_MBUTTON = 0x04 # Middle mouse button (three-button mouse) + +VK_XBUTTON1 = 0x05 # X1 mouse button +VK_XBUTTON2 = 0x06 # X2 mouse button + +VK_KANA = 0x15 # IME Kana mode +VK_HANGUL = 0x15 # IME Hangul mode +VK_JUNJA = 0x17 # IME Junja mode +VK_FINAL = 0x18 # IME final mode +VK_HANJA = 0x19 # IME Hanja mode +VK_KANJI = 0x19 # IME Kanji mode +VK_CONVERT = 0x1C # IME convert +VK_NONCONVERT = 0x1D # IME nonconvert +VK_ACCEPT = 0x1E # IME accept +VK_MODECHANGE = 0x1F # IME mode change request + +VK_PROCESSKEY = 0xE5 +VK_PACKET = 0xE7 +VK_ICO_HELP = 0xE3 +VK_ICO_00 = 0xE4 +VK_ICO_CLEAR = 0xE6 diff --git a/cefpython/web_plugin_info_cef3.pyx b/cefpython/web_plugin_info_cef3.pyx new file mode 100644 index 00000000..0c58fe98 --- /dev/null +++ b/cefpython/web_plugin_info_cef3.pyx @@ -0,0 +1,24 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef PyWebPluginInfo CreatePyWebPluginInfo( + CefRefPtr[CefWebPluginInfo] cefPlugin): + cdef PyWebPluginInfo pyPlugin = PyWebPluginInfo() + pyPlugin.cefPlugin = cefPlugin + return pyPlugin + +cdef class PyWebPluginInfo: + cdef CefRefPtr[CefWebPluginInfo] cefPlugin + + cpdef py_string GetName(self): + return CefToPyString(self.cefPlugin.get().GetName()) + + cpdef py_string GetPath(self): + return CefToPyString(self.cefPlugin.get().GetPath()) + + cpdef py_string GetVersion(self): + return CefToPyString(self.cefPlugin.get().GetVersion()) + + cpdef py_string GetDescription(self): + return CefToPyString(self.cefPlugin.get().GetDescription()) diff --git a/cefpython/web_request_cef1.pyx b/cefpython/web_request_cef1.pyx new file mode 100644 index 00000000..04ea3592 --- /dev/null +++ b/cefpython/web_request_cef1.pyx @@ -0,0 +1,209 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +# TODO: fix CefWebURLRequest memory corruption and restore weakrefs +# for PyWebRequest object. Right now getting memory corruption +# when CefRefPtr[CefWebURLRequest] is released after the request +# is completed. The memory corruption manifests itself with the +# "Segmentation Fault" error message or the strange "C function +# name could not be determined in the current C stack frame". +# See this topic on cython-users group: +# https://groups.google.com/d/topic/cython-users/FJZwHhqaCSI/discussion +# After CefWebURLRequest memory corruption is fixed restore weakrefs: +# 1. cdef object g_pyWebRequests = weakref.WeakValueDictionary() +# 2. Add property "cdef object __weakref__" in PyWebRequest +# When using normal dictionary for g_pyWebRequest then the memory +# corruption doesn't occur, but the PyWebRequest and CefWebURLRequest +# objects are never released, thus you have memory leaks, for now +# there is no other solution. See this topic on the CEF Forum: +# http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10710 +cdef object g_pyWebRequests = {} +cdef int g_webRequestMaxId = 0 + +# ------------------------------------------------------------------------------ +# WebRequest +# ------------------------------------------------------------------------------ + +# Static methods are not allowed in cdef classes, +# that's why we need a wrapper for PyWebRequest. + +class WebRequest: + State = { + "Unsent": cef_types.WUR_STATE_UNSENT, + "Started": cef_types.WUR_STATE_STARTED, + "HeadersReceived": cef_types.WUR_STATE_HEADERS_RECEIVED, + "Loading": cef_types.WUR_STATE_LOADING, + "Done": cef_types.WUR_STATE_DONE, + "Error": cef_types.WUR_STATE_ERROR, + "Abort": cef_types.WUR_STATE_ABORT, + } + + def __init__(self): + raise Exception("You cannot instantiate WebRequest directly, " + "use WebRequest.CreateWebRequest() static method") + + @staticmethod + def CreateWebRequest(request, webRequestClient): + if not isinstance(request, PyRequest): + raise Exception("Invalid request object") + return CreatePyWebRequest(request, webRequestClient) + +# ------------------------------------------------------------------------------ +# PyWebRequest +# ------------------------------------------------------------------------------ + +cdef PyWebRequest CreatePyWebRequest(PyRequest request, + object webRequestClient): + global g_pyWebRequests + cdef PyWebRequest webRequest = PyWebRequest(request, webRequestClient) + assert webRequest.webRequestId, "webRequest.webRequestId empty" + g_pyWebRequests[webRequest.webRequestId] = webRequest + return webRequest + +cdef PyWebRequest GetPyWebRequest(int webRequestId): + global g_pyWebRequests + if webRequestId in g_pyWebRequests: + return g_pyWebRequests[webRequestId] + return None + +cdef class PyWebRequest: + # cdef object __weakref__ # see g_pyWebRequests + cdef int webRequestId + cdef CefRefPtr[CefWebURLRequest] requester + cdef object pyWebRequestClient + + def __init__(self, PyRequest pyRequest, object pyWebRequestClient): + global g_webRequestMaxId + g_webRequestMaxId += 1 + self.webRequestId = g_webRequestMaxId + cdef CefRefPtr[WebRequestClient] cppWebRequestClient = ( + new WebRequestClient( + self.webRequestId)) + self.pyWebRequestClient = pyWebRequestClient + self.requester = ( + cef_web_urlrequest_static.CreateWebURLRequest( + pyRequest.cefRequest, + ( + cppWebRequestClient))) + + cdef object GetCallback(self, str funcName): + if hasattr(self.pyWebRequestClient, funcName) and ( + callable(getattr(self.pyWebRequestClient, funcName))): + return getattr(self.pyWebRequestClient, funcName) + + cpdef py_void Cancel(self): + self.requester.get().Cancel() + + cpdef int GetState(self) except *: + return self.requester.get().GetState() + +# ------------------------------------------------------------------------------ +# WebRequestClient +# ------------------------------------------------------------------------------ + +cdef public void WebRequestClient_OnStateChange( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + cef_types.cef_weburlrequest_state_t state + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnStateChange") + if callback: + callback(webRequest, state) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnRedirect( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + CefRefPtr[CefRequest] request, + CefRefPtr[CefResponse] response + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnRedirect") + if callback: + callback(webRequest, webRequest.pyRequest, + CreatePyResponse(response)) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnHeadersReceived( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + CefRefPtr[CefResponse] response + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnHeadersReceived") + if callback: + callback(webRequest, CreatePyResponse(response)) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnProgress( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + uint64_t bytesSent, + uint64_t totalBytesToBeSent + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnProgress") + if callback: + callback(webRequest, bytesSent, totalBytesToBeSent) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnData( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + void* data, + int dataLength + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnData") + if callback: + callback(webRequest, VoidPtrToString(data, dataLength)) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnError( + int webRequestId, + CefRefPtr[CefWebURLRequest] requester, + int errorCode + ) except * with gil: + cdef PyWebRequest webRequest + cdef object callback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + callback = webRequest.GetCallback("OnError") + if callback: + callback(webRequest, errorCode) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/web_request_cef3.pyx b/cefpython/web_request_cef3.pyx new file mode 100644 index 00000000..58d93bc4 --- /dev/null +++ b/cefpython/web_request_cef3.pyx @@ -0,0 +1,186 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef object g_pyWebRequests = weakref.WeakValueDictionary() +cdef int g_webRequestMaxId = 0 + +# ----------------------------------------------------------------------------- +# WebRequest +# ----------------------------------------------------------------------------- + +# Static methods are not allowed in cdef classes, +# that's why we need a wrapper for PyWebRequest. + +class WebRequest: + Status = { + "Unknown": cef_types.UR_UNKNOWN, + "Success": cef_types.UR_SUCCESS, + "Pending": cef_types.UR_IO_PENDING, + "Canceled": cef_types.UR_CANCELED, + "Failed": cef_types.UR_FAILED, + } + + def __init__(self): + raise Exception("You cannot instantiate WebRequest directly, " + "use WebRequest.CreateWebRequest() static method") + + @staticmethod + def ValidateClient(webRequestClient): + cdef list methods = ["OnRequestComplete", "OnUploadProgress", + "OnDownloadProgress", "OnDownloadData"] + for method in methods: + if webRequestClient and hasattr(webRequestClient, method) \ + and callable(getattr(webRequestClient, method)): + # Okay. + continue + else: + raise Exception("WebRequestClient object is missing method: " \ + "%s" % method) + + @staticmethod + def Create(request, webRequestClient): + if not isinstance(request, PyRequest): + raise Exception("Invalid request object") + WebRequest.ValidateClient(webRequestClient) + return CreatePyWebRequest(request, webRequestClient) + +# ----------------------------------------------------------------------------- +# PyWebRequest +# ----------------------------------------------------------------------------- + +cdef PyWebRequest CreatePyWebRequest(PyRequest request, + object webRequestClient): + global g_pyWebRequests + cdef PyWebRequest webRequest = PyWebRequest(request, webRequestClient) + assert webRequest.webRequestId, "webRequest.webRequestId empty" + g_pyWebRequests[webRequest.webRequestId] = webRequest + return webRequest + +cdef PyWebRequest GetPyWebRequest(int webRequestId): + global g_pyWebRequests + if webRequestId in g_pyWebRequests: + return g_pyWebRequests[webRequestId] + return None + +cdef class PyWebRequest: + cdef object __weakref__ # see g_pyWebRequests + cdef int webRequestId + cdef CefRefPtr[CefURLRequest] cefWebRequest + cdef object pyWebRequestClient + + def __init__(self, PyRequest pyRequest, object pyWebRequestClient): + global g_webRequestMaxId + g_webRequestMaxId += 1 + self.webRequestId = g_webRequestMaxId + cdef CefRefPtr[WebRequestClient] cppWebRequestClient = ( + new WebRequestClient( + self.webRequestId)) + self.pyWebRequestClient = pyWebRequestClient + self.cefWebRequest = (CefURLRequest_Create(\ + pyRequest.cefRequest, \ + (cppWebRequestClient))) + + cdef object GetCallback(self, str funcName): + if hasattr(self.pyWebRequestClient, funcName) and ( + callable(getattr(self.pyWebRequestClient, funcName))): + return getattr(self.pyWebRequestClient, funcName) + + cpdef PyRequest GetRequest(self): + cdef CefRefPtr[CefRequest] cefRequest = \ + self.cefWebRequest.get().GetRequest() + cdef PyRequest pyRequest = CreatePyRequest(cefRequest) + return pyRequest + + cpdef int GetRequestStatus(self) except *: + return self.cefWebRequest.get().GetRequestStatus() + + cpdef int GetRequestError(self) except *: + return self.cefWebRequest.get().GetRequestError() + + cpdef PyResponse GetResponse(self): + cdef CefRefPtr[CefResponse] cefResponse = \ + self.cefWebRequest.get().GetResponse() + cdef PyResponse pyResponse + # CefResponse may be NULL. + if cefResponse.get(): + pyResponse = CreatePyResponse(cefResponse) + return pyResponse + return None + + cpdef py_void Cancel(self): + self.cefWebRequest.get().Cancel() + +# ----------------------------------------------------------------------------- +# WebRequestClient +# ----------------------------------------------------------------------------- + +cdef public void WebRequestClient_OnUploadProgress( + int webRequestId, + CefRefPtr[CefURLRequest] cefWebRequest, + cef_types.uint64 current, + cef_types.uint64 total + ) except * with gil: + cdef PyWebRequest webRequest + cdef object userCallback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + userCallback = webRequest.GetCallback("OnUploadProgress") + if userCallback: + userCallback(webRequest, current, total) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnDownloadProgress( + int webRequestId, + CefRefPtr[CefURLRequest] cefWebRequest, + cef_types.uint64 current, + cef_types.uint64 total + ) except * with gil: + cdef PyWebRequest webRequest + cdef object userCallback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + userCallback = webRequest.GetCallback("OnDownloadProgress") + if userCallback: + userCallback(webRequest, current, total) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnDownloadData( + int webRequestId, + CefRefPtr[CefURLRequest] cefWebRequest, + const void* data, + size_t dataLength + ) except * with gil: + cdef PyWebRequest webRequest + cdef object userCallback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + userCallback = webRequest.GetCallback("OnDownloadData") + if userCallback: + userCallback(webRequest, VoidPtrToString(data, dataLength)) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) + +cdef public void WebRequestClient_OnRequestComplete( + int webRequestId, + CefRefPtr[CefURLRequest] cefWebRequest + ) except * with gil: + cdef PyWebRequest webRequest + cdef object userCallback + try: + webRequest = GetPyWebRequest(webRequestId) + if webRequest: + userCallback = webRequest.GetCallback("OnRequestComplete") + if userCallback: + userCallback(webRequest) + except: + (exc_type, exc_value, exc_trace) = sys.exc_info() + sys.excepthook(exc_type, exc_value, exc_trace) diff --git a/cefpython/window_info_cef1.pyx b/cefpython/window_info_cef1.pyx new file mode 100644 index 00000000..f7946ec9 --- /dev/null +++ b/cefpython/window_info_cef1.pyx @@ -0,0 +1,105 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef void SetCefWindowInfo( + CefWindowInfo& cefWindowInfo, + WindowInfo windowInfo + ) except *: + if not windowInfo.windowType: + raise Exception("WindowInfo: windowType is not set") + + # It is allowed to pass 0 as parentWindowHandle in OSR mode, but then + # some things like context menus and plugins may not display correctly. + if windowInfo.windowType != "offscreen": + if not windowInfo.parentWindowHandle: + raise Exception("WindowInfo: parentWindowHandle is not set") + + IF UNAME_SYSNAME == "Windows": + cdef RECT rect + cdef CefString cefString + + if windowInfo.windowType == "child": + IF UNAME_SYSNAME == "Windows": + if windowInfo.windowRect: + rect.left = int(windowInfo.windowRect[0]) + rect.top = int(windowInfo.windowRect[1]) + rect.right = int(windowInfo.windowRect[2]) + rect.bottom = int(windowInfo.windowRect[3]) + else: + GetClientRect( + windowInfo.parentWindowHandle, &rect) + cefWindowInfo.SetAsChild( + windowInfo.parentWindowHandle, rect) + ELIF UNAME_SYSNAME == "Darwin": + raise Exception("WindowInfo.SetAsChild() not implemented on Mac") + ELIF UNAME_SYSNAME == "Linux": + cefWindowInfo.SetAsChild( + windowInfo.parentWindowHandle) + + IF UNAME_SYSNAME == "Windows": + if windowInfo.windowType == "popup": + PyToCefString(windowInfo.windowName, cefString) + cefWindowInfo.SetAsPopup( + windowInfo.parentWindowHandle, cefString) + + IF not (CEF_VERSION == 1 and UNAME_SYSNAME == "Linux"): + if windowInfo.windowType == "offscreen": + cefWindowInfo.SetAsOffScreen( + windowInfo.parentWindowHandle) + cefWindowInfo.SetTransparentPainting( + int(windowInfo.transparentPainting)) + +cdef class WindowInfo: + cdef public str windowType + cdef public WindowHandle parentWindowHandle + cdef public list windowRect + cdef public py_string windowName + cdef public py_bool transparentPainting + + def __init__(self): + self.transparentPainting = False + + cpdef py_void SetAsChild(self, WindowHandle parentWindowHandle, + list windowRect=None): + if not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.windowType = "child" + self.parentWindowHandle = parentWindowHandle + IF UNAME_SYSNAME == "Darwin": + if not windowRect: + raise Exception("WindowInfo.SetAsChild() failed: " \ + "windowRect is required") + if windowRect: + if type(windowRect) == list and len(windowRect) == 4: + self.windowRect = [windowRect[0], windowRect[1], + windowRect[2], windowRect[3]] + else: + raise Exception("WindowInfo.SetAsChild() failed: " \ + "windowRect: invalid value") + + IF UNAME_SYSNAME == "Windows": + cpdef py_void SetAsPopup(self, WindowHandle parentWindowHandle, + py_string windowName): + if not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.parentWindowHandle = parentWindowHandle + self.windowType = "popup" + self.windowName = str(windowName) + + IF not (CEF_VERSION == 1 and UNAME_SYSNAME == "Linux"): + cpdef py_void SetAsOffscreen(self, + WindowHandle parentWindowHandle): + # It is allowed to pass 0 as parentWindowHandle. + if parentWindowHandle and \ + not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.parentWindowHandle = parentWindowHandle + self.windowType = "offscreen" + + cpdef py_void SetTransparentPainting(self, + py_bool transparentPainting): + self.transparentPainting = transparentPainting diff --git a/cefpython/window_info_cef3.pyx b/cefpython/window_info_cef3.pyx new file mode 100644 index 00000000..9a048c98 --- /dev/null +++ b/cefpython/window_info_cef3.pyx @@ -0,0 +1,108 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +cdef void SetCefWindowInfo( + CefWindowInfo& cefWindowInfo, + WindowInfo windowInfo + ) except *: + if not windowInfo.windowType: + raise Exception("WindowInfo: windowType is not set") + + # It is allowed to pass 0 as parentWindowHandle in OSR mode, but then + # some things like context menus and plugins may not display correctly. + if windowInfo.windowType != "offscreen": + if not windowInfo.parentWindowHandle: + raise Exception("WindowInfo: parentWindowHandle is not set") + + IF UNAME_SYSNAME == "Windows": + cdef RECT rect + cdef CefString cefString + + if windowInfo.windowType == "child": + IF UNAME_SYSNAME == "Windows": + if windowInfo.windowRect: + rect.left = int(windowInfo.windowRect[0]) + rect.top = int(windowInfo.windowRect[1]) + rect.right = int(windowInfo.windowRect[2]) + rect.bottom = int(windowInfo.windowRect[3]) + else: + GetClientRect( + windowInfo.parentWindowHandle, &rect) + cefWindowInfo.SetAsChild( + windowInfo.parentWindowHandle, rect) + ELIF UNAME_SYSNAME == "Darwin": + cefWindowInfo.SetAsChild( + windowInfo.parentWindowHandle, + int(windowInfo.windowRect[0]), + int(windowInfo.windowRect[1]), + int(windowInfo.windowRect[2]), + int(windowInfo.windowRect[3])) + ELIF UNAME_SYSNAME == "Linux": + cefWindowInfo.SetAsChild( + windowInfo.parentWindowHandle) + + IF UNAME_SYSNAME == "Windows": + if windowInfo.windowType == "popup": + PyToCefString(windowInfo.windowName, cefString) + cefWindowInfo.SetAsPopup( + windowInfo.parentWindowHandle, cefString) + + if windowInfo.windowType == "offscreen": + cefWindowInfo.SetAsOffScreen( + windowInfo.parentWindowHandle) + cefWindowInfo.SetTransparentPainting( + int(windowInfo.transparentPainting)) + +cdef class WindowInfo: + cdef public str windowType + cdef public WindowHandle parentWindowHandle + cdef public list windowRect + cdef public py_string windowName + cdef public py_bool transparentPainting + + def __init__(self): + self.transparentPainting = False + + cpdef py_void SetAsChild(self, WindowHandle parentWindowHandle, + list windowRect=None): + if not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.windowType = "child" + self.parentWindowHandle = parentWindowHandle + IF UNAME_SYSNAME == "Darwin": + if not windowRect: + raise Exception("WindowInfo.SetAsChild() failed: " \ + "windowRect is required") + if windowRect: + if type(windowRect) == list and len(windowRect) == 4: + self.windowRect = [windowRect[0], windowRect[1], + windowRect[2], windowRect[3]] + else: + raise Exception("WindowInfo.SetAsChild() failed: " \ + "windowRect: invalid value") + + IF UNAME_SYSNAME == "Windows": + cpdef py_void SetAsPopup(self, WindowHandle parentWindowHandle, + py_string windowName): + if not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.parentWindowHandle = parentWindowHandle + self.windowType = "popup" + self.windowName = str(windowName) + + cpdef py_void SetAsOffscreen(self, + WindowHandle parentWindowHandle): + # It is allowed to pass 0 as parentWindowHandle. + if parentWindowHandle and \ + not WindowUtils.IsWindowHandle(parentWindowHandle): + raise Exception("Invalid parentWindowHandle: %s" \ + % parentWindowHandle) + self.parentWindowHandle = parentWindowHandle + self.windowType = "offscreen" + + cpdef py_void SetTransparentPainting(self, + py_bool transparentPainting): + self.transparentPainting = transparentPainting diff --git a/cefpython/window_utils_linux.pyx b/cefpython/window_utils_linux.pyx new file mode 100644 index 00000000..e624ee97 --- /dev/null +++ b/cefpython/window_utils_linux.pyx @@ -0,0 +1,25 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class WindowUtils: + # You have to overwrite this class and provide implementations + # for these methods. + + @staticmethod + def GetParentHandle(WindowHandle windowHandle): + Debug("WindowUtils::GetParentHandle() not implemented (returns 0)") + return 0 + + @staticmethod + def IsWindowHandle(WindowHandle windowHandle): + Debug("WindowUtils::IsWindowHandle() not implemented (always True)") + return True + + @staticmethod + def gtk_plug_new(long long gdkNativeWindow): + return gtk_plug_new(gdkNativeWindow) + + @staticmethod + def gtk_widget_show(long long gtkWidgetPtr): + gtk_widget_show(gtkWidgetPtr) diff --git a/cefpython/window_utils_mac.pyx b/cefpython/window_utils_mac.pyx new file mode 100644 index 00000000..70561d9b --- /dev/null +++ b/cefpython/window_utils_mac.pyx @@ -0,0 +1,17 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class WindowUtils: + # You have to overwrite this class and provide implementations + # for these methods. + + @staticmethod + def GetParentHandle(WindowHandle windowHandle): + Debug("WindowUtils::GetParentHandle() not implemented (returns 0)") + return 0 + + @staticmethod + def IsWindowHandle(WindowHandle windowHandle): + Debug("WindowUtils::IsWindowHandle() not implemented (always True)") + return True diff --git a/cefpython/window_utils_win.pyx b/cefpython/window_utils_win.pyx new file mode 100644 index 00000000..888eb696 --- /dev/null +++ b/cefpython/window_utils_win.pyx @@ -0,0 +1,143 @@ +# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved. +# License: New BSD License. +# Website: http://code.google.com/p/cefpython/ + +class WindowUtils: + + @staticmethod + def OnSetFocus(int windowHandle, long msg, long wparam, long lparam): + cdef PyBrowser pyBrowser = GetBrowserByWindowHandle(windowHandle) + if not pyBrowser: + return 0 + pyBrowser.SetFocus(True) + return 0 + + @staticmethod + def OnSize(int windowHandle, long msg, long wparam, long lparam): + cdef PyBrowser pyBrowser = GetBrowserByWindowHandle(windowHandle) + if not pyBrowser: + return DefWindowProc(windowHandle, msg, wparam, lparam) + + cdef HWND innerHwnd = pyBrowser.GetWindowHandle() + cdef RECT rect2 + GetClientRect(windowHandle, &rect2) + + cdef HDWP hdwp = BeginDeferWindowPos(1) + hdwp = DeferWindowPos(hdwp, innerHwnd, NULL, + rect2.left, rect2.top, + rect2.right - rect2.left, + rect2.bottom - rect2.top, + SWP_NOZORDER) + EndDeferWindowPos(hdwp) + + return DefWindowProc(windowHandle, msg, wparam, lparam) + + @staticmethod + def OnEraseBackground(int windowHandle, long msg, long wparam, + long lparam): + cdef PyBrowser pyBrowser = GetBrowserByWindowHandle(windowHandle) + if not pyBrowser: + return DefWindowProc(windowHandle, msg, wparam, lparam) + + # Dont erase the background if the browser window has been loaded, + # this avoids flashing. + if pyBrowser.GetWindowHandle(): + return 0 + + return DefWindowProc(windowHandle, msg, wparam, lparam) + + @staticmethod + def SetTitle(PyBrowser pyBrowser, str pyTitle): + # Each browser window should have a title (Issue 3). + # When popup is created, the window that sits in taskbar + # has no title. + if not pyTitle: + return + + cdef WindowHandle windowHandle + if pyBrowser.GetUserData("__outerWindowHandle"): + windowHandle = pyBrowser.GetUserData("__outerWindowHandle") + else: + windowHandle = pyBrowser.GetWindowHandle() + + assert windowHandle, ( + "WindowUtils.SetTitle() failed: windowHandle is empty") + + # Get window title. + cdef int sizeOfTitle = 100 + cdef wchar_t* widecharTitle = ( + calloc(sizeOfTitle, wchar_t_size)) + GetWindowTextW(windowHandle, widecharTitle, sizeOfTitle) + cdef str currentTitle = WidecharToPyString(widecharTitle) + free(widecharTitle) + + # Must keep alive while c_str() is passed. + cdef CefString cefTitle + PyToCefString(pyTitle, cefTitle) + + if pyBrowser.GetUserData("__outerWindowHandle"): + if not currentTitle: + SetWindowTextW(windowHandle, cefTitle.ToWString().c_str()) + else: + # For independent popups we always change title to what page + # is displayed currently. + SetWindowTextW(windowHandle, cefTitle.ToWString().c_str()) + + @staticmethod + def SetIcon(PyBrowser pyBrowser, py_string icon="inherit"): + # `icon` parameter is not implemented. + # Popup window inherits icon from the main window. + + if pyBrowser.GetUserData("__outerWindowHandle"): + return None + + windowHandle = pyBrowser.GetWindowHandle() + assert windowHandle, ( + "WindowUtils.SetIcon() failed: windowHandle is empty") + + iconBig = SendMessage( + windowHandle, WM_GETICON, ICON_BIG, 0) + iconSmall = SendMessage( + windowHandle, WM_GETICON, ICON_SMALL, 0) + + cdef int parentWindowHandle + + if not iconBig and not iconSmall: + parentWindowHandle = pyBrowser.GetOpenerWindowHandle() + parentIconBig = SendMessage( + parentWindowHandle, WM_GETICON, ICON_BIG, 0) + parentIconSmall = SendMessage( + parentWindowHandle, WM_GETICON, ICON_SMALL, 0) + + # If parent is main application window, then + # GetOpenerWindowHandle() returned innerWindowHandle + # of the parent window, try again. + + if not parentIconBig and not parentIconSmall: + parentWindowHandle = GetParent(parentWindowHandle) + + Debug("WindowUtils.SetIcon(): popup inherits icon from " + "parent window: %s" % parentWindowHandle) + + parentIconBig = SendMessage( + parentWindowHandle, WM_GETICON, ICON_BIG, 0) + parentIconSmall = SendMessage( + parentWindowHandle, WM_GETICON, ICON_SMALL, 0) + + if parentIconBig: + SendMessage(windowHandle, WM_SETICON, + ICON_BIG, parentIconBig) + if parentIconSmall: + SendMessage(windowHandle, WM_SETICON, + ICON_SMALL, parentIconSmall) + + @staticmethod + def GetParentHandle(int windowHandle): + return GetParent(windowHandle) + + @staticmethod + def IsWindowHandle(int windowHandle): + IF UNAME_SYSNAME == "Windows": + return bool(IsWindow(windowHandle)) + ELSE: + return False