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/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..626079ff --- /dev/null +++ b/cefpython/browser.pyx @@ -0,0 +1,843 @@ +# 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): + self.GetCefBrowser().get().SendMouseClickEvent(x, y, + mouseButtonType, bool(mouseUp), clickCount) + + cpdef py_void SendMouseMoveEvent(self, int x, int y, + py_bool mouseLeave): + self.GetCefBrowser().get().SendMouseMoveEvent(x, y, + bool(mouseLeave)) + + cpdef py_void SendMouseWheelEvent(self, int x, int y, + int deltaX, int deltaY): + 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, x, y, + cef_types.cef_mouse_button_type_t mouseButtonType, + py_bool mouseUp, int clickCount): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + """ + TODO: allow to pass modifiers which represents + bit flags describing any pressed modifier keys. + See cef_event_flags_t for values. + 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, + """ + mouseEvent.modifiers = 0 + self.GetCefBrowserHost().get().SendMouseClickEvent(mouseEvent, + mouseButtonType, bool(mouseUp), clickCount) + + cpdef py_void SendMouseMoveEvent(self, int x, int y, + py_bool mouseLeave): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + mouseEvent.modifiers = 0 + self.GetCefBrowserHost().get().SendMouseMoveEvent(mouseEvent, + bool(mouseLeave)) + + cpdef py_void SendMouseWheelEvent(self, int x, int y, + int deltaX, int deltaY): + cdef CefMouseEvent mouseEvent + mouseEvent.x = x + mouseEvent.y = y + mouseEvent.modifiers = 0 + 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