From 764c23203386b10bd37271ffdd966244bf49071b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 4 Aug 2016 12:44:46 +0200 Subject: [PATCH] Split inspector into web{engine,kit}inspector --- qutebrowser/browser/commands.py | 41 ++----- qutebrowser/browser/inspector.py | 111 ++++++++++++++++++ .../browser/webengine/webengineinspector.py | 70 +++-------- qutebrowser/browser/webkit/webkitinspector.py | 41 ++----- 4 files changed, 146 insertions(+), 117 deletions(-) create mode 100644 qutebrowser/browser/inspector.py diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 77811e0e4..416719c67 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -40,9 +40,8 @@ import pygments.formatters from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners from qutebrowser.config import config, configexc -from qutebrowser.browser import urlmarks, browsertab -from qutebrowser.browser.webkit import (webelem, webkitinspector, downloads, - mhtml) +from qutebrowser.browser import urlmarks, browsertab, inspector +from qutebrowser.browser.webkit import webelem, downloads, mhtml from qutebrowser.keyinput import modeman from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils, objreg, utils, typing) @@ -1228,35 +1227,17 @@ class CommandDispatcher: headers in the network tab. """ tab = self._current_widget() - if tab.data.inspector is None: - if not config.get('general', 'developer-extras'): - raise cmdexc.CommandError( - "Please enable developer-extras before using the " - "webinspector!") + # FIXME:qtwebengine have a proper API for this + page = tab._widget.page() # pylint: disable=protected-access - # FIXME:qtwebengine have a proper API for this - if tab.backend == usertypes.Backend.QtWebKit: - tab.data.inspector = webkitinspector.WebInspector() - page = tab._widget.page() # pylint: disable=protected-access - tab.data.inspector.setPage(page) - tab.data.inspector.show() - elif tab.backend == usertypes.Backend.QtWebEngine: - from qutebrowser.browser.webengine import webengineinspector - tab.data.inspector = webengineinspector.WebInspector() - try: - tab.data.inspector.load() - except webengineinspector.WebInspectorError as e: - raise cmdexc.CommandError(e) - tab.data.inspector.show() - elif tab.data.inspector.isVisible(): - tab.data.inspector.hide() - else: - if not config.get('general', 'developer-extras'): - raise cmdexc.CommandError( - "Please enable developer-extras before using the " - "webinspector!") + try: + if tab.data.inspector is None: + tab.data.inspector = inspector.create() + tab.data.inspector.inspect(page) else: - tab.data.inspector.show() + tab.data.inspector.toggle(page) + except inspector.WebInspectorError as e: + raise cmdexc.CommandError(e) @cmdutils.register(instance='command-dispatcher', scope='window', backend=usertypes.Backend.QtWebKit) diff --git a/qutebrowser/browser/inspector.py b/qutebrowser/browser/inspector.py new file mode 100644 index 000000000..b3e3e0a74 --- /dev/null +++ b/qutebrowser/browser/inspector.py @@ -0,0 +1,111 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2015-2016 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Base class for a QtWebKit/QtWebEngine web inspector.""" + +import base64 +import binascii + +from PyQt5.QtWebKitWidgets import QWebInspector + +from qutebrowser.utils import log, objreg +from qutebrowser.misc import miscwidgets +from qutebrowser.config import config + + +def create(parent=None): + """Get a WebKitInspector/WebEngineInspector. + + Args: + parent: The Qt parent to set. + """ + # Importing modules here so we don't depend on QtWebEngine without the + # argument and to avoid circular imports. + if objreg.get('args').backend == 'webengine': + from qutebrowser.browser.webengine import webengineinspector + return webengineinspector.WebEngineInspector(parent) + else: + from qutebrowser.browser.webkit import webkitinspector + return webkitinspector.WebKitInspector(parent) + + +class WebInspectorError(Exception): + + """Raised when the inspector could not be initialized.""" + + pass + + +class AbstractWebInspector(QWebInspector): + + """A customized WebInspector which stores its geometry.""" + + def __init__(self, parent=None): + super().__init__(parent) + self._widget = None + self._layout = None + self._load_state_geometry() + + def _set_widget(self, widget): + self._widget = widget + self._layout = miscwidgets.WrapperLayout(self._widget, self) + self.setFocusProxy(self._widget) + self._widget.setParent(self) + + def _load_state_geometry(self): + """Load the geometry from the state file.""" + state_config = objreg.get('state-config') + try: + data = state_config['geometry']['inspector'] + geom = base64.b64decode(data, validate=True) + except KeyError: + # First start + pass + except binascii.Error: + log.misc.exception("Error while reading geometry") + else: + log.init.debug("Loading geometry from {}".format(geom)) + ok = self.restoreGeometry(geom) + if not ok: + log.init.warning("Error while loading geometry.") + + def closeEvent(self, e): + """Save the geometry when closed.""" + state_config = objreg.get('state-config') + data = bytes(self.saveGeometry()) + geom = base64.b64encode(data).decode('ASCII') + state_config['geometry']['inspector'] = geom + super().closeEvent(e) + + def _check_developer_extras(self): + """Check if developer-extras are enabled.""" + if not config.get('general', 'developer-extras'): + raise WebInspectorError( + "Please enable developer-extras before using the " + "webinspector!") + + def inspect(self, page): + """Inspect the given QWeb(Engine)Page.""" + raise NotImplementedError + + def toggle(self, page): + if self._widget.isVisible(): + self.hide() + else: + self.inspect(page) diff --git a/qutebrowser/browser/webengine/webengineinspector.py b/qutebrowser/browser/webengine/webengineinspector.py index f248bd148..b0c0a25bf 100644 --- a/qutebrowser/browser/webengine/webengineinspector.py +++ b/qutebrowser/browser/webengine/webengineinspector.py @@ -17,79 +17,37 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Customized QWebInspector.""" +"""Customized QWebInspector for QtWebEngine.""" import os -import base64 -import binascii from PyQt5.QtCore import QUrl -from PyQt5.QtWidgets import QWidget # pylint: disable=no-name-in-module,import-error,useless-suppression from PyQt5.QtWebEngineWidgets import QWebEngineView # pylint: enable=no-name-in-module,import-error,useless-suppression -from qutebrowser.utils import log, objreg -from qutebrowser.misc import miscwidgets +from qutebrowser.browser import inspector -# FIXME:qtwebengine should we move the geometry stuff to some mixin? +class WebEngineInspector(inspector.AbstractWebInspector): - -class WebInspectorError(Exception): - - """Raised when the inspector could not be initialized.""" - - pass - - -class WebInspector(QWidget): - - """A web inspector for QtWebEngine which stores its geometry.""" - - # FIXME:qtwebengine unify this with the WebKit inspector as far as possible + """A web inspector for QtWebEngine.""" def __init__(self, parent=None): super().__init__(parent) self.port = None - self._view = QWebEngineView() - self._layout = miscwidgets.WrapperLayout(self._view, self) - self.setFocusProxy(self._view) - self._view.setParent(self) - self._load_state_geometry() + view = QWebEngineView() + self._set_widget(view) - def load(self): + def inspect(self, _page): """Set up the inspector.""" - envvar = 'QTWEBENGINE_REMOTE_DEBUGGING' - if envvar not in os.environ: - raise WebInspectorError( + self._check_developer_extras() + try: + port = int(os.environ['QTWEBENGINE_REMOTE_DEBUGGING']) + except KeyError: + raise inspector.WebInspectorError( "Debugging is not set up correctly. Did you restart after " "setting developer-extras?") - port = int(os.environ[envvar]) url = QUrl('http://localhost:{}/'.format(port)) - self._view.load(url) - - def closeEvent(self, e): - """Save the geometry when closed.""" - state_config = objreg.get('state-config') - data = bytes(self.saveGeometry()) - geom = base64.b64encode(data).decode('ASCII') - state_config['geometry']['inspector'] = geom - super().closeEvent(e) - - def _load_state_geometry(self): - """Load the geometry from the state file.""" - state_config = objreg.get('state-config') - try: - data = state_config['geometry']['inspector'] - geom = base64.b64decode(data, validate=True) - except KeyError: - # First start - pass - except binascii.Error: - log.misc.exception("Error while reading geometry") - else: - log.init.debug("Loading geometry from {}".format(geom)) - ok = self.restoreGeometry(geom) - if not ok: - log.init.warning("Error while loading geometry.") + self._widget.load(url) + self.show() diff --git a/qutebrowser/browser/webkit/webkitinspector.py b/qutebrowser/browser/webkit/webkitinspector.py index f62d9b20a..1a54ec784 100644 --- a/qutebrowser/browser/webkit/webkitinspector.py +++ b/qutebrowser/browser/webkit/webkitinspector.py @@ -17,45 +17,24 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Customized QWebInspector.""" +"""Customized QWebInspector for QtWebKit.""" -import base64 -import binascii from PyQt5.QtWebKitWidgets import QWebInspector -from qutebrowser.utils import log, objreg +from qutebrowser.browser import inspector -class WebInspector(QWebInspector): +class WebKitInspector(inspector.AbstractWebInspector): - """A customized WebInspector which stores its geometry.""" + """A web inspector for QtWebKit.""" def __init__(self, parent=None): super().__init__(parent) - self._load_state_geometry() + qwebinspector = QWebInspector() + self._set_widget(qwebinspector) - def closeEvent(self, e): - """Save the geometry when closed.""" - state_config = objreg.get('state-config') - data = bytes(self.saveGeometry()) - geom = base64.b64encode(data).decode('ASCII') - state_config['geometry']['inspector'] = geom - super().closeEvent(e) - - def _load_state_geometry(self): - """Load the geometry from the state file.""" - state_config = objreg.get('state-config') - try: - data = state_config['geometry']['inspector'] - geom = base64.b64decode(data, validate=True) - except KeyError: - # First start - pass - except binascii.Error: - log.misc.exception("Error while reading geometry") - else: - log.init.debug("Loading geometry from {}".format(geom)) - ok = self.restoreGeometry(geom) - if not ok: - log.init.warning("Error while loading geometry.") + def inspect(self, page): + self._check_developer_extras() + self._widget.setPage(page) + self.show()