Sun, 08 May 2016 19:42:41 +0200
Corrected a code style issue.
# -*- coding: utf-8 -*- # Copyright (c) 2008 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the helpbrowser using QWebView. """ from __future__ import unicode_literals try: str = unicode # __IGNORE_EXCEPTION__ except NameError: pass from PyQt5.QtCore import pyqtSlot, QUrl, QTimer, QEventLoop, QPoint from PyQt5.QtGui import QDesktopServices from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineSettings from PyQt5.QtWebChannel import QWebChannel from WebBrowser.WebBrowserWindow import WebBrowserWindow from .JavaScript.ExternalJsObject import ExternalJsObject from .Tools.WebHitTestResult import WebHitTestResult import Preferences class WebBrowserPage(QWebEnginePage): """ Class implementing an enhanced web page. """ def __init__(self, parent=None): """ Constructor @param parent parent widget of this window (QWidget) """ super(WebBrowserPage, self).__init__( WebBrowserWindow.webProfile(), parent) self.__setupWebChannel() self.featurePermissionRequested.connect( self.__featurePermissionRequested) self.authenticationRequired.connect( WebBrowserWindow.networkManager().authentication) self.proxyAuthenticationRequired.connect( WebBrowserWindow.networkManager().proxyAuthentication) self.fullScreenRequested.connect(self.__fullScreenRequested) self.urlChanged.connect(self.__urlChanged) def acceptNavigationRequest(self, url, type_, isMainFrame): """ Public method to determine, if a request may be accepted. @param url URL to navigate to @type QUrl @param type_ type of the navigation request @type QWebEnginePage.NavigationType @param isMainFrame flag indicating, that the request originated from the main frame @type bool @return flag indicating acceptance @rtype bool """ scheme = url.scheme() if scheme == "mailto": QDesktopServices.openUrl(url) return False # AdBlock if url.scheme() == "abp": if WebBrowserWindow.adBlockManager().addSubscriptionFromUrl(url): return False return QWebEnginePage.acceptNavigationRequest(self, url, type_, isMainFrame) @pyqtSlot(QUrl) def __urlChanged(self, url): """ Private slot to handle changes of the URL. @param url new URL @type QUrl """ if not url.isEmpty() and url.scheme() == "eric" and \ not self.isJavaScriptEnabled(): self.setJavaScriptEnabled(True) self.triggerAction(QWebEnginePage.Reload) @classmethod def userAgent(cls, resolveEmpty=False): """ Class method to get the global user agent setting. @param resolveEmpty flag indicating to resolve an empty user agent (boolean) @return user agent string (string) """ agent = Preferences.getWebBrowser("UserAgent") if agent == "" and resolveEmpty: agent = cls.userAgentForUrl(QUrl()) return agent @classmethod def setUserAgent(cls, agent): """ Class method to set the global user agent string. @param agent new current user agent string (string) """ Preferences.setWebBrowser("UserAgent", agent) @classmethod def userAgentForUrl(cls, url): """ Class method to determine the user agent for the given URL. @param url URL to determine user agent for (QUrl) @return user agent string (string) """ agent = WebBrowserWindow.userAgentsManager().userAgentForUrl(url) if agent == "": # no agent string specified for the given host -> use global one agent = Preferences.getWebBrowser("UserAgent") if agent == "": # no global agent string specified -> use default one agent = WebBrowserWindow.webProfile().httpUserAgent() return agent def __featurePermissionRequested(self, url, feature): """ Private slot handling a feature permission request. @param url url requesting the feature @type QUrl @param feature requested feature @type QWebEnginePage.Feature """ manager = WebBrowserWindow.featurePermissionManager() manager.requestFeaturePermission(self, url, feature) def execJavaScript(self, script): """ Public method to execute a JavaScript function synchroneously. @param script JavaScript script source to be executed @type str @return result of the script @rtype depending upon script result """ loop = QEventLoop() resultDict = {"res": None} QTimer.singleShot(500, loop.quit) def resultCallback(res, resDict=resultDict): if loop and loop.isRunning(): resDict["res"] = res loop.quit() self.runJavaScript(script, resultCallback) loop.exec_() return resultDict["res"] def setJavaScriptEnabled(self, enable): """ Public method to enable JavaScript. @param enable flag indicating the enabled state to be set @type bool """ if not self.url().isEmpty() and self.url().scheme() == "eric": enable = True self.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, enable) def isJavaScriptEnabled(self): """ Public method to test, if JavaScript is enabled. @return flag indicating the state of the JavaScript support @rtype bool """ return self.settings().testAttribute( QWebEngineSettings.JavascriptEnabled) def scroll(self, x, y): """ Public method to scroll by the given amount of pixels. @param x horizontal scroll value @type int @param y vertical scroll value @type int """ self.runJavaScript( "window.scrollTo(window.scrollX + {0}, window.scrollY + {1})" .format(x, y) ) def mapToViewport(self, pos): """ Public method to map a position to the viewport. @param pos position to be mapped @type QPoint @return viewport position @rtype QPoint """ return QPoint(pos.x() // self.zoomFactor(), pos.y() // self.zoomFactor()) def hitTestContent(self, pos): """ Public method to test the content at a specified position. @param pos position to execute the test at @type QPoint @return test result object @rtype WebHitTestResult """ return WebHitTestResult(self, pos) def __setupWebChannel(self): """ Private method to setup a web channel to our external object. """ oldChannel = self.webChannel() newChannel = QWebChannel(self) newChannel.registerObject("eric_object", ExternalJsObject(self)) self.setWebChannel(newChannel) if oldChannel: del oldChannel.registeredObjects["eric_object"] del oldChannel def certificateError(self, error): """ Public method to handle SSL certificate errors. @param error object containing the certificate error information @type QWebEngineCertificateError @return flag indicating to ignore this error @rtype bool """ return WebBrowserWindow.networkManager().certificateError( error, self.view()) def __fullScreenRequested(self, request): """ Private slot handling a full screen request. @param request reference to the full screen request @type QWebEngineFullScreenRequest """ self.view().requestFullScreen(request.toggleOn()) accepted = request.toggleOn() == self.view().isFullScreen() if accepted: request.accept() else: request.reject() ############################################## ## Methods below deal with JavaScript messages ############################################## def javaScriptConsoleMessage(self, level, message, lineNumber, sourceId): """ Public method to show a console message. @param level severity @type QWebEnginePage.JavaScriptConsoleMessageLevel @param message message to be shown @type str @param lineNumber line number of an error @type int @param sourceId source URL causing the error @type str """ self.view().mainWindow().javascriptConsole().javaScriptConsoleMessage( level, message, lineNumber, sourceId)