From e9d606a78268b2a9cf9695a06906fb74d03732e0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 11 Jul 2016 12:08:54 +0200 Subject: [PATCH] Move load_status / SSL errors to AbstractTab --- qutebrowser/browser/browsertab.py | 40 ++++++++++++++++++- qutebrowser/browser/webengine/webenginetab.py | 8 +--- qutebrowser/browser/webengine/webview.py | 15 ++++++- qutebrowser/browser/webkit/webkittab.py | 7 +--- qutebrowser/browser/webkit/webview.py | 33 --------------- 5 files changed, 56 insertions(+), 47 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 8a7701402..96f4aa980 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -27,7 +27,7 @@ from PyQt5.QtWidgets import QWidget, QLayout from qutebrowser.keyinput import modeman from qutebrowser.config import config -from qutebrowser.utils import utils, objreg, usertypes, message +from qutebrowser.utils import utils, objreg, usertypes, message, log tab_id_gen = itertools.count(0) @@ -424,6 +424,11 @@ class AbstractTab(QWidget): history: The AbstractHistory for the current tab. registry: The ObjectRegistry associated with this tab. + _load_status: loading status of this page + Accessible via load_status() method. + _has_ssl_errors: Whether SSL errors happened. + Needs to be set by subclasses. + for properties, see WebView/WebEngineView docs. Signals: @@ -431,6 +436,7 @@ class AbstractTab(QWidget): new_tab_requested: Emitted when a new tab should be opened with the given URL. + load_status_changed: The loading status changed """ window_close_requested = pyqtSignal() @@ -467,6 +473,8 @@ class AbstractTab(QWidget): self._layout = None self._widget = None self._progress = 0 + self._has_ssl_errors = False + self._load_status = usertypes.LoadStatus.none self.backend = None def _set_widget(self, widget): @@ -482,17 +490,45 @@ class AbstractTab(QWidget): widget.setParent(self) self.setFocusProxy(widget) + def _set_load_status(self, val): + """Setter for load_status.""" + if not isinstance(val, usertypes.LoadStatus): + raise TypeError("Type {} is no LoadStatus member!".format(val)) + log.webview.debug("load status for {}: {}".format(repr(self), val)) + self._load_status = val + self.load_status_changed.emit(val.name) + @pyqtSlot() def _on_load_started(self): self._progress = 0 + self._has_ssl_errors = False self.data.viewing_source = False + self._set_load_status(usertypes.LoadStatus.loading) self.load_started.emit() + @pyqtSlot(bool) + def _on_load_finished(self, ok): + if ok and not self._has_ssl_errors: + if self.url().scheme() == 'https': + self._set_load_status(usertypes.LoadStatus.success_https) + else: + self._set_load_status(usertypes.LoadStatus.success) + + elif ok: + self._set_load_status(usertypes.LoadStatus.warn) + else: + self._set_load_status(usertypes.LoadStatus.error) + self.load_finished.emit(ok) + @pyqtSlot(int) def _on_load_progress(self, perc): self._progress = perc self.load_progress.emit(perc) + @pyqtSlot() + def _on_ssl_errors(self): + self._has_ssl_errors = True + def url(self): raise NotImplementedError @@ -500,7 +536,7 @@ class AbstractTab(QWidget): return self._progress def load_status(self): - raise NotImplementedError + return self._load_status def openurl(self, url): raise NotImplementedError diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 70ffa3a95..3e331ee91 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -266,10 +266,6 @@ class WebEngineTab(browsertab.AbstractTab): def url(self): return self._widget.url() - def load_status(self): - log.stub() - return usertypes.LoadStatus.success - def dump_async(self, callback, *, plain=False): if plain: self._widget.page().toPlainText(callback) @@ -320,9 +316,9 @@ class WebEngineTab(browsertab.AbstractTab): page.loadProgress.connect(self._on_load_progress) page.loadStarted.connect(self._on_load_started) view.titleChanged.connect(self.title_changed) - page.loadFinished.connect(self.load_finished) + page.loadFinished.connect(self._on_load_finished) + page.certificate_error.connect(self._on_ssl_errors) # FIXME:qtwebengine stub this? # view.iconChanged.connect(self.icon_changed) # view.scroll.pos_changed.connect(self.scroll.perc_changed) # view.url_text_changed.connect(self.url_text_changed) - # view.load_status_changed.connect(self.load_status_changed) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index cf7a14e97..112f71406 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -22,7 +22,7 @@ from PyQt5.QtCore import pyqtSignal, Qt, QPoint # pylint: disable=no-name-in-module,import-error,useless-suppression -from PyQt5.QtWebEngineWidgets import QWebEngineView +from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage # pylint: enable=no-name-in-module,import-error,useless-suppression @@ -32,6 +32,10 @@ class WebEngineView(QWebEngineView): mouse_wheel_zoom = pyqtSignal(QPoint) + def __init__(self, parent=None): + super().__init__(parent) + self.setPage(WebEnginePage(self)) + def wheelEvent(self, e): """Zoom on Ctrl-Mousewheel. @@ -43,3 +47,12 @@ class WebEngineView(QWebEngineView): self.mouse_wheel_zoom.emit(e.angleDelta()) else: super().wheelEvent(e) + + +class WebEnginePage(QWebEnginePage): + + certificate_error = pyqtSignal() + + def certificateError(self, error): + self.certificate_error.emit() + return super().certificateError(error) diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index 6629c33de..0588572c4 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -472,9 +472,6 @@ class WebKitTab(browsertab.AbstractTab): def url(self): return self._widget.cur_url - def load_status(self): - return self._widget.load_status - def dump_async(self, callback, *, plain=False): frame = self._widget.page().mainFrame() if plain: @@ -524,15 +521,15 @@ class WebKitTab(browsertab.AbstractTab): view.scroll_pos_changed.connect(self.scroll.perc_changed) view.titleChanged.connect(self.title_changed) view.url_text_changed.connect(self.url_text_changed) - view.load_status_changed.connect(self.load_status_changed) view.shutting_down.connect(self.shutting_down) + page.networkAccessManager().sslErrors.connect(self._on_ssl_errors) # Make sure we emit an appropriate status when loading finished. While # Qt has a bool "ok" attribute for loadFinished, it always is True when # using error pages... # See https://github.com/The-Compiler/qutebrowser/issues/84 frame.loadFinished.connect(lambda: - self.load_finished.emit( + self._on_load_finished( not self._widget.page().error_occurred)) # Emit iconChanged with a QIcon like QWebEngineView does. diff --git a/qutebrowser/browser/webkit/webview.py b/qutebrowser/browser/webkit/webview.py index f86cfa99c..b1a7b5913 100644 --- a/qutebrowser/browser/webkit/webview.py +++ b/qutebrowser/browser/webkit/webview.py @@ -43,10 +43,8 @@ class WebView(QWebView): hintmanager: The HintManager instance for this view. scroll_pos: The current scroll position as (x%, y%) tuple. statusbar_message: The current javascript statusbar message. - load_status: loading status of this page (index into LoadStatus) win_id: The window ID of the view. _tab_id: The tab ID of the view. - _has_ssl_errors: Whether SSL errors occurred during loading. _old_scroll_pos: The old scroll position. _check_insertmode: If True, in mouseReleaseEvent we should check if we need to enter/leave insert mode. @@ -58,7 +56,6 @@ class WebView(QWebView): arg 1: x-position in %. arg 2: y-position in %. linkHovered: QWebPages linkHovered signal exposed. - load_status_changed: The loading status changed url_text_changed: Current URL string changed. mouse_wheel_zoom: Emitted when the page should be zoomed because the mousewheel was used with ctrl. @@ -68,7 +65,6 @@ class WebView(QWebView): scroll_pos_changed = pyqtSignal(int, int) linkHovered = pyqtSignal(str, str, str) - load_status_changed = pyqtSignal(str) url_text_changed = pyqtSignal(str) shutting_down = pyqtSignal() mouse_wheel_zoom = pyqtSignal(QPoint) @@ -81,12 +77,10 @@ class WebView(QWebView): self.setStyle(QStyleFactory.create('Fusion')) self.tab = tab self.win_id = win_id - self.load_status = usertypes.LoadStatus.none self._check_insertmode = False self.scroll_pos = (-1, -1) self.statusbar_message = '' self._old_scroll_pos = (-1, -1) - self._has_ssl_errors = False self._ignore_wheel_event = False self._set_bg_color() self.cur_url = QUrl() @@ -126,14 +120,11 @@ class WebView(QWebView): page = webpage.BrowserPage(self.win_id, self._tab_id, self) self.setPage(page) page.linkHovered.connect(self.linkHovered) - page.mainFrame().loadStarted.connect(self.on_load_started) page.mainFrame().loadFinished.connect(self.on_load_finished) page.mainFrame().initialLayoutCompleted.connect( self.on_initial_layout_completed) page.statusBarMessage.connect( lambda msg: setattr(self, 'statusbar_message', msg)) - page.networkAccessManager().sslErrors.connect( - lambda *args: setattr(self, '_has_ssl_errors', True)) return page def __repr__(self): @@ -153,14 +144,6 @@ class WebView(QWebView): # deleted pass - def _set_load_status(self, val): - """Setter for load_status.""" - if not isinstance(val, usertypes.LoadStatus): - raise TypeError("Type {} is no LoadStatus member!".format(val)) - log.webview.debug("load status for {}: {}".format(repr(self), val)) - self.load_status = val - self.load_status_changed.emit(val.name) - def _set_bg_color(self): """Set the webpage background color as configured.""" col = config.get('colors', 'webpage.bg') @@ -349,12 +332,6 @@ class WebView(QWebView): self.setFocus() QApplication.postEvent(self, evt) - @pyqtSlot() - def on_load_started(self): - """Leave insert/hint mode and set vars when a new page is loading.""" - self._has_ssl_errors = False - self._set_load_status(usertypes.LoadStatus.loading) - @pyqtSlot() def on_load_finished(self): """Handle a finished page load. @@ -364,16 +341,6 @@ class WebView(QWebView): See https://github.com/The-Compiler/qutebrowser/issues/84 """ ok = not self.page().error_occurred - if ok and not self._has_ssl_errors: - if self.cur_url.scheme() == 'https': - self._set_load_status(usertypes.LoadStatus.success_https) - else: - self._set_load_status(usertypes.LoadStatus.success) - - elif ok: - self._set_load_status(usertypes.LoadStatus.warn) - else: - self._set_load_status(usertypes.LoadStatus.error) if not self.title(): self.titleChanged.emit(self.url().toDisplayString()) self._handle_auto_insert_mode(ok)