WebBrowser/WebBrowserPage.py

branch
QtWebEngine
changeset 4710
370a38e03efe
parent 4631
5c1a96925da4
child 4715
79009bc4acd5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/WebBrowserPage.py	Mon Feb 01 20:03:22 2016 +0100
@@ -0,0 +1,716 @@
+# -*- 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
+except NameError:
+    pass
+
+from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, \
+    QUrl, QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, \
+    QRect, QFile, QPoint, QByteArray, qVersion
+from PyQt5.QtGui import QDesktopServices, QClipboard, QMouseEvent, QColor, \
+    QPalette
+from PyQt5.QtWidgets import qApp, QStyle, QMenu, QApplication, QInputDialog, \
+    QLineEdit, QLabel, QToolTip, QFrame, QDialog
+from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
+##from PyQt5.QtWebKit import QWebSettings
+##from PyQt5.QtWebKitWidgets import QWebView, QWebPage
+from PyQt5.QtWebEngineWidgets import QWebEnginePage
+try:
+    from PyQt5.QtWebKit import QWebElement
+except ImportError:
+    pass
+from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
+import sip
+
+from E5Gui import E5MessageBox, E5FileDialog
+
+import WebBrowser
+import WebBrowser.WebBrowserWindow
+
+import Preferences
+import UI.PixmapCache
+import Globals
+
+try:
+    from PyQt5.QtNetwork import QSslCertificate
+    SSL_AVAILABLE = True
+except ImportError:
+    SSL_AVAILABLE = False
+
+###############################################################################
+##
+##
+##class JavaScriptExternalObject(QObject):
+##    """
+##    Class implementing an external javascript object to add search providers.
+##    """
+##    def __init__(self, mw, parent=None):
+##        """
+##        Constructor
+##        
+##        @param mw reference to the main window 8HelpWindow)
+##        @param parent reference to the parent object (QObject)
+##        """
+##        super(JavaScriptExternalObject, self).__init__(parent)
+##        
+##        self.__mw = mw
+##    
+##    @pyqtSlot(str)
+##    def AddSearchProvider(self, url):
+##        """
+##        Public slot to add a search provider.
+##        
+##        @param url url of the XML file defining the search provider (string)
+##        """
+##        self.__mw.openSearchManager().addEngine(QUrl(url))
+##
+##
+##class LinkedResource(object):
+##    """
+##    Class defining a data structure for linked resources.
+##    """
+##    def __init__(self):
+##        """
+##        Constructor
+##        """
+##        self.rel = ""
+##        self.type_ = ""
+##        self.href = ""
+##        self.title = ""
+##
+###############################################################################
+##
+##
+##class JavaScriptEricObject(QObject):
+##    """
+##    Class implementing an external javascript object to search via the
+##    startpage.
+##    """
+##    # these must be in line with the strings used by the javascript part of
+##    # the start page
+##    translations = [
+##        QT_TRANSLATE_NOOP("JavaScriptEricObject",
+##                          "Welcome to eric6 Web Browser!"),
+##        QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric6 Web Browser"),
+##        QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"),
+##        QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric6"),
+##    ]
+##    
+##    def __init__(self, mw, parent=None):
+##        """
+##        Constructor
+##        
+##        @param mw reference to the main window 8HelpWindow)
+##        @param parent reference to the parent object (QObject)
+##        """
+##        super(JavaScriptEricObject, self).__init__(parent)
+##        
+##        self.__mw = mw
+##    
+##    @pyqtSlot(str, result=str)
+##    def translate(self, trans):
+##        """
+##        Public method to translate the given string.
+##        
+##        @param trans string to be translated (string)
+##        @return translation (string)
+##        """
+##        if trans == "QT_LAYOUT_DIRECTION":
+##            # special handling to detect layout direction
+##            if qApp.isLeftToRight():
+##                return "LTR"
+##            else:
+##                return "RTL"
+##        
+##        return self.tr(trans)
+##    
+##    @pyqtSlot(result=str)
+##    def providerString(self):
+##        """
+##        Public method to get a string for the search provider.
+##        
+##        @return string for the search provider (string)
+##        """
+##        return self.tr("Search results provided by {0}")\
+##            .format(self.__mw.openSearchManager().currentEngineName())
+##    
+##    @pyqtSlot(str, result=str)
+##    def searchUrl(self, searchStr):
+##        """
+##        Public method to get the search URL for the given search term.
+##        
+##        @param searchStr search term (string)
+##        @return search URL (string)
+##        """
+##        return bytes(
+##            self.__mw.openSearchManager().currentEngine()
+##            .searchUrl(searchStr).toEncoded()).decode()
+##
+###############################################################################
+
+
+class WebBrowserPage(QWebEnginePage):
+    """
+    Class implementing an enhanced web page.
+    """
+##    _webPluginFactory = None
+##    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent parent widget of this window (QWidget)
+        """
+        super(WebBrowserPage, self).__init__(parent)
+        
+##        self.setPluginFactory(self.webPluginFactory())
+##        
+##        self.__lastRequest = None
+##        self.__lastRequestType = QWebPage.NavigationTypeOther
+##        
+##        import Helpviewer.HelpWindow
+##        from .Network.NetworkAccessManagerProxy import \
+##            NetworkAccessManagerProxy
+##        self.__proxy = NetworkAccessManagerProxy(self)
+##        self.__proxy.setWebPage(self)
+##        self.__proxy.setPrimaryNetworkAccessManager(
+##            Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
+##        self.setNetworkAccessManager(self.__proxy)
+##        
+##        self.__sslConfiguration = None
+##        self.__proxy.finished.connect(self.__managerFinished)
+##        
+        self.__adBlockedEntries = []
+        self.loadStarted.connect(self.__loadStarted)
+##        
+##        self.saveFrameStateRequested.connect(
+##            self.__saveFrameStateRequested)
+##        self.restoreFrameStateRequested.connect(
+##            self.__restoreFrameStateRequested)
+        self.featurePermissionRequested.connect(
+            self.__featurePermissionRequested)
+    
+    def acceptNavigationRequest(self, url, type_, isMainFrame):
+        """
+        Protected 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
+        """
+##        self.__lastRequest = request
+##        if self.__lastRequest.url() != request.url() or \
+##           type_ != QWebPage.NavigationTypeOther:
+##            self.__lastRequestType = type_
+        
+        # TODO: Qt 5.6: move to handleUnknownProtocol
+        scheme = url.scheme()
+        if scheme == "mailto":
+            QDesktopServices.openUrl(url)
+            return False
+        
+        # AdBlock
+        if url.scheme() == "abp":
+            if WebBrowser.WebBrowserWindow.WebBrowserWindow.adBlockManager()\
+                    .addSubscriptionFromUrl(url):
+                return False
+##        
+##        if type_ == QWebPage.NavigationTypeFormResubmitted:
+##            res = E5MessageBox.yesNo(
+##                self.view(),
+##                self.tr("Resending POST request"),
+##                self.tr(
+##                    """In order to display the site, the request along with"""
+##                    """ all the data must be sent once again, which may lead"""
+##                    """ to some unexpected behaviour of the site e.g. the"""
+##                    """ same action might be performed once again. Do you"""
+##                    """ want to continue anyway?"""),
+##                icon=E5MessageBox.Warning)
+##            if not res:
+##                return False
+        
+        return QWebEnginePage.acceptNavigationRequest(self, url, type_,
+                                                      isMainFrame)
+##    
+##    def populateNetworkRequest(self, request):
+##        """
+##        Public method to add data to a network request.
+##        
+##        @param request reference to the network request object
+##            (QNetworkRequest)
+##        """
+##        try:
+##            request.setAttribute(QNetworkRequest.User + 100, self)
+##            if self.__lastRequest.url() == request.url():
+##                request.setAttribute(QNetworkRequest.User + 101,
+##                                     self.__lastRequestType)
+##                if self.__lastRequestType == \
+##                        QWebPage.NavigationTypeLinkClicked:
+##                    request.setRawHeader(b"X-Eric6-UserLoadAction",
+##                                         QByteArray(b"1"))
+##        except TypeError:
+##            pass
+##    
+##    def pageAttributeId(self):
+##        """
+##        Public method to get the attribute id of the page attribute.
+##        
+##        @return attribute id of the page attribute (integer)
+##        """
+##        return QNetworkRequest.User + 100
+##    
+##    def supportsExtension(self, extension):
+##        """
+##        Public method to check the support for an extension.
+##        
+##        @param extension extension to test for (QWebPage.Extension)
+##        @return flag indicating the support of extension (boolean)
+##        """
+##        try:
+##            if extension in [QWebPage.ErrorPageExtension,
+##                             QWebPage.ChooseMultipleFilesExtension]:
+##                return True
+##        except AttributeError:
+##            pass
+##        
+##        return QWebPage.supportsExtension(self, extension)
+##    
+##    def extension(self, extension, option, output):
+##        """
+##        Public method to implement a specific extension.
+##        
+##        @param extension extension to be executed (QWebPage.Extension)
+##        @param option provides input to the extension
+##            (QWebPage.ExtensionOption)
+##        @param output stores the output results (QWebPage.ExtensionReturn)
+##        @return flag indicating a successful call of the extension (boolean)
+##        """
+##        if extension == QWebPage.ChooseMultipleFilesExtension:
+##            info = sip.cast(option,
+##                            QWebPage.ChooseMultipleFilesExtensionOption)
+##            files = sip.cast(output,
+##                             QWebPage.ChooseMultipleFilesExtensionReturn)
+##            if info is None or files is None:
+##                return super(HelpWebPage, self).extension(
+##                    extension, option, output)
+##            
+##            suggestedFileName = ""
+##            if info.suggestedFileNames:
+##                suggestedFileName = info.suggestedFileNames[0]
+##            
+##            files.fileNames = E5FileDialog.getOpenFileNames(
+##                None,
+##                self.tr("Select files to upload..."),
+##                suggestedFileName)
+##            return True
+##        
+##        if extension == QWebPage.ErrorPageExtension:
+##            info = sip.cast(option, QWebPage.ErrorPageExtensionOption)
+##            
+##            errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn)
+##            urlString = bytes(info.url.toEncoded()).decode()
+##            errorPage.baseUrl = info.url
+##            if info.domain == QWebPage.QtNetwork and \
+##               info.error == QNetworkReply.ProtocolUnknownError:
+##                url = QUrl(info.url)
+##                res = E5MessageBox.yesNo(
+##                    None,
+##                    self.tr("Protocol Error"),
+##                    self.tr("""Open external application for {0}-link?\n"""
+##                            """URL: {1}""").format(
+##                        url.scheme(), url.toString(
+##                            QUrl.PrettyDecoded | QUrl.RemovePassword)),
+##                    yesDefault=True)
+##                
+##                if res:
+##                    QDesktopServices.openUrl(url)
+##                return True
+##            elif info.domain == QWebPage.QtNetwork and \
+##                info.error == QNetworkReply.ContentAccessDenied and \
+##                    info.errorString.startswith("AdBlockRule:"):
+##                if info.frame != info.frame.page().mainFrame():
+##                    # content in <iframe>
+##                    docElement = info.frame.page().mainFrame()\
+##                        .documentElement()
+##                    for element in docElement.findAll("iframe"):
+##                        src = element.attribute("src")
+##                        if src in info.url.toString():
+##                            element.setAttribute("style", "display:none;")
+##                    return False
+##                else:
+##                    # the whole page is blocked
+##                    rule = info.errorString.replace("AdBlockRule:", "")
+##                    title = self.tr("Content blocked by AdBlock Plus")
+##                    message = self.tr(
+##                        "Blocked by rule: <i>{0}</i>").format(rule)
+##                    
+##                    htmlFile = QFile(":/html/adblockPage.html")
+##                    htmlFile.open(QFile.ReadOnly)
+##                    html = htmlFile.readAll()
+##                    html = html.replace(
+##                        "@FAVICON@", "qrc:icons/adBlockPlus16.png")
+##                    html = html.replace(
+##                        "@IMAGE@", "qrc:icons/adBlockPlus64.png")
+##                    html = html.replace("@TITLE@", title.encode("utf8"))
+##                    html = html.replace("@MESSAGE@", message.encode("utf8"))
+##                    errorPage.content = html
+##                    return True
+##            
+##            if info.domain == QWebPage.QtNetwork and \
+##               info.error == QNetworkReply.OperationCanceledError and \
+##               info.errorString == "eric6:No Error":
+##                return False
+##            
+##            if info.domain == QWebPage.WebKit and info.error == 203:
+##                # "Loading is handled by the media engine"
+##                return False
+##            
+##            title = self.tr("Error loading page: {0}").format(urlString)
+##            htmlFile = QFile(":/html/notFoundPage.html")
+##            htmlFile.open(QFile.ReadOnly)
+##            html = htmlFile.readAll()
+##            pixmap = qApp.style()\
+##                .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48)
+##            imageBuffer = QBuffer()
+##            imageBuffer.open(QIODevice.ReadWrite)
+##            if pixmap.save(imageBuffer, "PNG"):
+##                html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64())
+##            pixmap = qApp.style()\
+##                .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16)
+##            imageBuffer = QBuffer()
+##            imageBuffer.open(QIODevice.ReadWrite)
+##            if pixmap.save(imageBuffer, "PNG"):
+##                html = html.replace(
+##                    "@FAVICON@", imageBuffer.buffer().toBase64())
+##            html = html.replace("@TITLE@", title.encode("utf8"))
+##            html = html.replace("@H1@", info.errorString.encode("utf8"))
+##            html = html.replace(
+##                "@H2@", self.tr("When connecting to: {0}.")
+##                .format(urlString).encode("utf8"))
+##            html = html.replace(
+##                "@LI-1@",
+##                self.tr("Check the address for errors such as "
+##                        "<b>ww</b>.example.org instead of "
+##                        "<b>www</b>.example.org").encode("utf8"))
+##            html = html.replace(
+##                "@LI-2@",
+##                self.tr(
+##                    "If the address is correct, try checking the network "
+##                    "connection.").encode("utf8"))
+##            html = html.replace(
+##                "@LI-3@",
+##                self.tr(
+##                    "If your computer or network is protected by a firewall "
+##                    "or proxy, make sure that the browser is permitted to "
+##                    "access the network.").encode("utf8"))
+##            html = html.replace(
+##                "@LI-4@",
+##                self.tr("If your cache policy is set to offline browsing,"
+##                        "only pages in the local cache are available.")
+##                .encode("utf8"))
+##            html = html.replace(
+##                "@BUTTON@", self.tr("Try Again").encode("utf8"))
+##            errorPage.content = html
+##            return True
+##        
+##        return QWebPage.extension(self, extension, option, output)
+    
+    def __loadStarted(self):
+        """
+        Private method to handle the loadStarted signal.
+        """
+        self.__adBlockedEntries = []
+##    
+##    def addAdBlockRule(self, rule, url):
+##        """
+##        Public slot to add an AdBlock rule to the page.
+##        
+##        @param rule AdBlock rule to add (AdBlockRule)
+##        @param url URL that matched the rule (QUrl)
+##        """
+##        from .AdBlock.AdBlockPage import AdBlockedPageEntry
+##        entry = AdBlockedPageEntry(rule, url)
+##        if entry not in self.__adBlockedEntries:
+##            self.__adBlockedEntries.append(entry)
+##    
+##    def getAdBlockedPageEntries(self):
+##        """
+##        Public method to get the list of AdBlock page entries.
+##        
+##        @return list of AdBlock page entries (list of AdBlockedPageEntry)
+##        """
+##        return self.__adBlockedEntries
+    
+    # TODO: re-enable once User Agent Manager is done
+##    def userAgent(self, resolveEmpty=False):
+##        """
+##        Public 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 = self.userAgentForUrl(QUrl())
+##        return agent
+##    
+##    def setUserAgent(self, agent):
+##        """
+##        Public method to set the global user agent string.
+##        
+##        @param agent new current user agent string (string)
+##        """
+##        Preferences.setHelp("UserAgent", agent)
+##    
+##    def userAgentForUrl(self, url):
+##        """
+##        Public method to determine the user agent for the given URL.
+##        
+##        @param url URL to determine user agent for (QUrl)
+##        @return user agent string (string)
+##        """
+##        import Helpviewer.HelpWindow
+##        agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager()\
+##            .userAgentForUrl(url)
+##        if agent == "":
+##            # no agent string specified for the given host -> use global one
+##            agent = Preferences.getHelp("UserAgent")
+##            if agent == "":
+##                # no global agent string specified -> use default one
+##                agent = QWebPage.userAgentForUrl(self, url)
+##        return agent
+##    
+##    def __managerFinished(self, reply):
+##        """
+##        Private slot to handle a finished reply.
+##        
+##        This slot is used to get SSL related information for a reply.
+##        
+##        @param reply reference to the finished reply (QNetworkReply)
+##        """
+##        try:
+##            frame = reply.request().originatingObject()
+##        except AttributeError:
+##            frame = None
+##        
+##        mainFrameRequest = frame == self.mainFrame()
+##        
+##        if mainFrameRequest and \
+##           self.__sslConfiguration is not None and \
+##           reply.url() == self.mainFrame().url():
+##            self.__sslConfiguration = None
+##        
+##        if reply.error() == QNetworkReply.NoError and \
+##           mainFrameRequest and \
+##           self.__sslConfiguration is None and \
+##           reply.url().scheme().lower() == "https" and \
+##           reply.url() == self.mainFrame().url():
+##            self.__sslConfiguration = reply.sslConfiguration()
+##            self.__sslConfiguration.url = QUrl(reply.url())
+##        
+##        if reply.error() == QNetworkReply.NoError and \
+##           mainFrameRequest and \
+##           reply.url() == self.mainFrame().url():
+##            modified = reply.header(QNetworkRequest.LastModifiedHeader)
+##            if modified and modified.isValid():
+##                import Helpviewer.HelpWindow
+##                manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()
+##                from .Bookmarks.BookmarkNode import BookmarkNode
+##                for bookmark in manager.bookmarksForUrl(reply.url()):
+##                    manager.setTimestamp(bookmark, BookmarkNode.TsModified,
+##                                         modified)
+    
+##    def getSslCertificate(self):
+##        """
+##        Public method to get a reference to the SSL certificate.
+##        
+##        @return amended SSL certificate (QSslCertificate)
+##        """
+##        if self.__sslConfiguration is None:
+##            return None
+##        
+##        sslInfo = self.__sslConfiguration.peerCertificate()
+##        sslInfo.url = QUrl(self.__sslConfiguration.url)
+##        return sslInfo
+##    
+##    def getSslCertificateChain(self):
+##        """
+##        Public method to get a reference to the SSL certificate chain.
+##        
+##        @return SSL certificate chain (list of QSslCertificate)
+##        """
+##        if self.__sslConfiguration is None:
+##            return []
+##        
+##        chain = self.__sslConfiguration.peerCertificateChain()
+##        return chain
+##    
+##    def getSslConfiguration(self):
+##        """
+##        Public method to return a reference to the current SSL configuration.
+##        
+##        @return reference to the SSL configuration in use (QSslConfiguration)
+##        """
+##        return self.__sslConfiguration
+##    
+##    def showSslInfo(self, pos):
+##        """
+##        Public slot to show some SSL information for the loaded page.
+##        
+##        @param pos position to show the info at (QPoint)
+##        """
+##        if SSL_AVAILABLE and self.__sslConfiguration is not None:
+##            from E5Network.E5SslInfoWidget import E5SslInfoWidget
+##            widget = E5SslInfoWidget(
+##                self.mainFrame().url(), self.__sslConfiguration, self.view())
+##            widget.showAt(pos)
+##        else:
+##            E5MessageBox.warning(
+##                self.view(),
+##                self.tr("SSL Info"),
+##                self.tr("""This site does not contain SSL information."""))
+##    
+##    def hasValidSslInfo(self):
+##        """
+##        Public method to check, if the page has a valid SSL certificate.
+##        
+##        @return flag indicating a valid SSL certificate (boolean)
+##        """
+##        if self.__sslConfiguration is None:
+##            return False
+##        
+##        certList = self.__sslConfiguration.peerCertificateChain()
+##        if not certList:
+##            return False
+##        
+##        certificateDict = Globals.toDict(
+##            Preferences.Prefs.settings.value("Ssl/CaCertificatesDict"))
+##        for server in certificateDict:
+##            localCAList = QSslCertificate.fromData(certificateDict[server])
+##            for cert in certList:
+##                if cert in localCAList:
+##                    return True
+##        
+##        if qVersion() >= "5.0.0":
+##            for cert in certList:
+##                if cert.isBlacklisted():
+##                    return False
+##        else:
+##            for cert in certList:
+##                if not cert.isValid():
+##                    return False
+##        
+##        return True
+    
+##    @classmethod
+##    def webPluginFactory(cls):
+##        """
+##        Class method to get a reference to the web plug-in factory
+##        instance.
+##        
+##        @return reference to the web plug-in factory instance (WebPluginFactory
+##        """
+##        if cls._webPluginFactory is None:
+##            from .WebPlugins.WebPluginFactory import WebPluginFactory
+##            cls._webPluginFactory = WebPluginFactory()
+##        
+##        return cls._webPluginFactory
+##    
+##    def event(self, evt):
+##        """
+##        Public method implementing the event handler.
+##        
+##        @param evt reference to the event (QEvent)
+##        @return flag indicating that the event was handled (boolean)
+##        """
+##        if evt.type() == QEvent.Leave:
+##            # Fake a mouse move event just outside of the widget to trigger
+##            # the WebKit event handler's mouseMoved function. This implements
+##            # the interesting mouse-out behavior like invalidating scrollbars.
+##            fakeEvent = QMouseEvent(QEvent.MouseMove, QPoint(0, -1),
+##                                    Qt.NoButton, Qt.NoButton, Qt.NoModifier)
+##            return super(HelpWebPage, self).event(fakeEvent)
+##        
+##        return super(HelpWebPage, self).event(evt)
+##    
+##    def __saveFrameStateRequested(self, frame, itm):
+##        """
+##        Private slot to save the page state (i.e. zoom level and scroll
+##        position).
+##        
+##        Note: Code is based on qutebrowser.
+##        
+##        @param frame frame to be saved
+##        @type QWebFrame
+##        @param itm web history item to be saved
+##        @type QWebHistoryItem
+##        """
+##        try:
+##            if frame != self.mainFrame():
+##                return
+##        except RuntimeError:
+##            # With Qt 5.2.1 (Ubuntu Trusty) we get this when closing a tab:
+##            #     RuntimeError: wrapped C/C++ object of type BrowserPage has
+##            #     been deleted
+##            # Since the information here isn't that important for closing web
+##            # views anyways, we ignore this error.
+##            return
+##        data = {
+##            'zoom': frame.zoomFactor(),
+##            'scrollPos': frame.scrollPosition(),
+##        }
+##        itm.setUserData(data)
+##    
+##    def __restoreFrameStateRequested(self, frame):
+##        """
+##        Private slot to restore scroll position and zoom level from
+##        history.
+##        
+##        Note: Code is based on qutebrowser.
+##        
+##        @param frame frame to be restored
+##        @type QWebFrame
+##        """
+##        if frame != self.mainFrame():
+##            return
+##        
+##        data = self.history().currentItem().userData()
+##        if data is None:
+##            return
+##        
+##        if 'zoom' in data:
+##            frame.page().view().setZoomValue(int(data['zoom'] * 100),
+##                                             saveValue=False)
+##        
+##        if 'scrollPos' in data and frame.scrollPosition() == QPoint(0, 0):
+##            frame.setScrollPosition(data['scrollPos'])
+    
+    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 = WebBrowser.WebBrowserWindow.WebBrowserWindow\
+            .featurePermissionManager()
+        manager.requestFeaturePermission(self, frame, feature)

eric ide

mercurial