eric6/WebBrowser/WebInspector.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7192
a22eee00b052
diff -r f99d60d6b59b -r 2602857055c5 eric6/WebBrowser/WebInspector.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric6/WebBrowser/WebInspector.py	Sun Apr 14 15:09:21 2019 +0200
@@ -0,0 +1,217 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a QWebEngineView to load the web inspector in.
+"""
+
+from __future__ import unicode_literals
+try:
+    str = unicode           # __IGNORE_EXCEPTION__
+except NameError:
+    pass
+
+import json
+import os
+
+from PyQt5.QtCore import pyqtSignal, QSize, QUrl
+from PyQt5.QtNetwork import QNetworkRequest
+from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, \
+    QWebEngineSettings
+
+from Globals import qVersionTuple
+
+import Preferences
+
+_VIEWS = []
+
+
+class WebInspector(QWebEngineView):
+    """
+    Class implementing a QWebEngineView to load the web inspector in.
+    
+    @signal inspectorClosed emitted to indicate the closing of the inspector
+        window
+    """
+    inspectorClosed = pyqtSignal()
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(WebInspector, self).__init__(parent)
+        
+        self.__view = None
+        self.__inspectElement = False
+        
+        self.__reloadGeometry()
+        
+        registerView(self)
+        
+        self.page().windowCloseRequested.connect(self.close)
+        self.page().loadFinished.connect(self.__loadFinished)
+    
+    def closeEvent(self, evt):
+        """
+        Protected method to save the geometry when closed.
+        
+        @param evt event object
+        @type QCloseEvent
+        """
+        Preferences.setGeometry("WebInspectorGeometry", self.saveGeometry())
+        super(WebInspector, self).closeEvent(evt)
+        
+        if evt.isAccepted():
+            self.inspectorClosed.emit()
+
+    def __reloadGeometry(self):
+        """
+        Private method to restore the geometry.
+        """
+        geom = Preferences.getGeometry("WebInspectorGeometry")
+        if geom.isEmpty():
+            s = QSize(600, 600)
+            self.resize(s)
+        else:
+            self.restoreGeometry(geom)
+    
+    def setView(self, view, inspectElement=False):
+        """
+        Public method to connect a view to this inspector.
+        
+        @param view reference to the view object
+        @type WebBrowserView
+        @param inspectElement flag indicating to start a web inspection
+        @type bool
+        """
+        self.__view = view
+        if not self.isEnabled():
+            return
+        
+        self.__inspectElement = inspectElement
+        
+        try:
+            self.page().setInspectedPage(self.__view.page())
+        except AttributeError:
+            # pre Qt 5.11
+            port = Preferences.getWebBrowser("WebInspectorPort")
+            inspectorUrl = QUrl("http://localhost:{0}".format(port))
+            
+            from WebBrowser.WebBrowserWindow import WebBrowserWindow
+            self.__reply = WebBrowserWindow.networkManager().get(
+                QNetworkRequest(inspectorUrl.resolved(QUrl("json/list"))))
+            self.__reply.finished.connect(self.__inspectorReplyFinished)
+    
+    def __inspectorReplyFinished(self):
+        """
+        Private slot handling the reply.
+        """
+        # used for pre Qt 5.11
+        result = str(self.__reply.readAll(), encoding="utf8")
+        
+        self.__reply.deleteLater()
+        self.__reply = None
+        
+        pageUrl = QUrl()
+        try:
+            index = _VIEWS.index(self.__view)
+        except ValueError:
+            index = -1
+        try:
+            clients = json.loads(result)
+            if len(clients) > index:
+                port = Preferences.getWebBrowser("WebInspectorPort")
+                inspectorUrl = QUrl("http://localhost:{0}".format(port))
+                
+                client = clients[index]
+                pageUrl = inspectorUrl.resolved(
+                    QUrl(client["devtoolsFrontendUrl"]))
+            self.load(pageUrl)
+            pushView(self)
+            self.show()
+        except json.JSONDecodeError:
+            # ignore silently
+            pass
+    
+    def inspectElement(self):
+        """
+        Public method to inspect an element.
+        """
+        self.__inspectElement = True
+    
+    @classmethod
+    def isEnabled(cls):
+        """
+        Class method to check, if the web inspector is enabled.
+        
+        @return flag indicating the enabled state
+        @rtype bool
+        """
+        if qVersionTuple() < (5, 11, 0):
+            if not os.getenv("QTWEBENGINE_REMOTE_DEBUGGING"):
+                return False
+        
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        if not WebBrowserWindow.webSettings().testAttribute(
+                QWebEngineSettings.JavascriptEnabled):
+            return False
+        
+        if qVersionTuple() < (5, 11, 0):
+            return Preferences.getWebBrowser("WebInspectorEnabled")
+        else:
+            return True
+    
+    def __loadFinished(self):
+        """
+        Private slot handling the finished signal.
+        """
+        if self.__inspectElement:
+            self.__view.triggerPageAction(QWebEnginePage.InspectElement)
+            self.__inspectElement = False
+
+
+def registerView(view):
+    """
+    Function to register a view.
+    
+    @param view reference to the view
+    @type WebBrowserView
+    """
+    if _VIEWS is None:
+        return
+    
+    _VIEWS.insert(0, view)
+
+
+def unregisterView(view):
+    """
+    Function to unregister a view.
+    
+    @param view reference to the view
+    @type WebBrowserView
+    """
+    if _VIEWS is None:
+        return
+    
+    if view in _VIEWS:
+        _VIEWS.remove(view)
+
+
+def pushView(view):
+    """
+    Function to push a view to the front of the list.
+    
+    @param view reference to the view
+    @type WebBrowserView
+    """
+    if _VIEWS is None:
+        return
+    
+    if view in _VIEWS:
+        _VIEWS.remove(view)
+    _VIEWS.insert(0, view)

eric ide

mercurial