Move load_status / SSL errors to AbstractTab

This commit is contained in:
Florian Bruhin 2016-07-11 12:08:54 +02:00
parent 6ae232d8fc
commit e9d606a782
5 changed files with 56 additions and 47 deletions

View File

@ -27,7 +27,7 @@ from PyQt5.QtWidgets import QWidget, QLayout
from qutebrowser.keyinput import modeman from qutebrowser.keyinput import modeman
from qutebrowser.config import config 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) tab_id_gen = itertools.count(0)
@ -424,6 +424,11 @@ class AbstractTab(QWidget):
history: The AbstractHistory for the current tab. history: The AbstractHistory for the current tab.
registry: The ObjectRegistry associated with this 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. for properties, see WebView/WebEngineView docs.
Signals: Signals:
@ -431,6 +436,7 @@ class AbstractTab(QWidget):
new_tab_requested: Emitted when a new tab should be opened with the new_tab_requested: Emitted when a new tab should be opened with the
given URL. given URL.
load_status_changed: The loading status changed
""" """
window_close_requested = pyqtSignal() window_close_requested = pyqtSignal()
@ -467,6 +473,8 @@ class AbstractTab(QWidget):
self._layout = None self._layout = None
self._widget = None self._widget = None
self._progress = 0 self._progress = 0
self._has_ssl_errors = False
self._load_status = usertypes.LoadStatus.none
self.backend = None self.backend = None
def _set_widget(self, widget): def _set_widget(self, widget):
@ -482,17 +490,45 @@ class AbstractTab(QWidget):
widget.setParent(self) widget.setParent(self)
self.setFocusProxy(widget) 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() @pyqtSlot()
def _on_load_started(self): def _on_load_started(self):
self._progress = 0 self._progress = 0
self._has_ssl_errors = False
self.data.viewing_source = False self.data.viewing_source = False
self._set_load_status(usertypes.LoadStatus.loading)
self.load_started.emit() 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) @pyqtSlot(int)
def _on_load_progress(self, perc): def _on_load_progress(self, perc):
self._progress = perc self._progress = perc
self.load_progress.emit(perc) self.load_progress.emit(perc)
@pyqtSlot()
def _on_ssl_errors(self):
self._has_ssl_errors = True
def url(self): def url(self):
raise NotImplementedError raise NotImplementedError
@ -500,7 +536,7 @@ class AbstractTab(QWidget):
return self._progress return self._progress
def load_status(self): def load_status(self):
raise NotImplementedError return self._load_status
def openurl(self, url): def openurl(self, url):
raise NotImplementedError raise NotImplementedError

View File

@ -266,10 +266,6 @@ class WebEngineTab(browsertab.AbstractTab):
def url(self): def url(self):
return self._widget.url() return self._widget.url()
def load_status(self):
log.stub()
return usertypes.LoadStatus.success
def dump_async(self, callback, *, plain=False): def dump_async(self, callback, *, plain=False):
if plain: if plain:
self._widget.page().toPlainText(callback) self._widget.page().toPlainText(callback)
@ -320,9 +316,9 @@ class WebEngineTab(browsertab.AbstractTab):
page.loadProgress.connect(self._on_load_progress) page.loadProgress.connect(self._on_load_progress)
page.loadStarted.connect(self._on_load_started) page.loadStarted.connect(self._on_load_started)
view.titleChanged.connect(self.title_changed) 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? # FIXME:qtwebengine stub this?
# view.iconChanged.connect(self.icon_changed) # view.iconChanged.connect(self.icon_changed)
# view.scroll.pos_changed.connect(self.scroll.perc_changed) # view.scroll.pos_changed.connect(self.scroll.perc_changed)
# view.url_text_changed.connect(self.url_text_changed) # view.url_text_changed.connect(self.url_text_changed)
# view.load_status_changed.connect(self.load_status_changed)

View File

@ -22,7 +22,7 @@
from PyQt5.QtCore import pyqtSignal, Qt, QPoint from PyQt5.QtCore import pyqtSignal, Qt, QPoint
# pylint: disable=no-name-in-module,import-error,useless-suppression # 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 # pylint: enable=no-name-in-module,import-error,useless-suppression
@ -32,6 +32,10 @@ class WebEngineView(QWebEngineView):
mouse_wheel_zoom = pyqtSignal(QPoint) mouse_wheel_zoom = pyqtSignal(QPoint)
def __init__(self, parent=None):
super().__init__(parent)
self.setPage(WebEnginePage(self))
def wheelEvent(self, e): def wheelEvent(self, e):
"""Zoom on Ctrl-Mousewheel. """Zoom on Ctrl-Mousewheel.
@ -43,3 +47,12 @@ class WebEngineView(QWebEngineView):
self.mouse_wheel_zoom.emit(e.angleDelta()) self.mouse_wheel_zoom.emit(e.angleDelta())
else: else:
super().wheelEvent(e) super().wheelEvent(e)
class WebEnginePage(QWebEnginePage):
certificate_error = pyqtSignal()
def certificateError(self, error):
self.certificate_error.emit()
return super().certificateError(error)

View File

@ -472,9 +472,6 @@ class WebKitTab(browsertab.AbstractTab):
def url(self): def url(self):
return self._widget.cur_url return self._widget.cur_url
def load_status(self):
return self._widget.load_status
def dump_async(self, callback, *, plain=False): def dump_async(self, callback, *, plain=False):
frame = self._widget.page().mainFrame() frame = self._widget.page().mainFrame()
if plain: if plain:
@ -524,15 +521,15 @@ class WebKitTab(browsertab.AbstractTab):
view.scroll_pos_changed.connect(self.scroll.perc_changed) view.scroll_pos_changed.connect(self.scroll.perc_changed)
view.titleChanged.connect(self.title_changed) view.titleChanged.connect(self.title_changed)
view.url_text_changed.connect(self.url_text_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) 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 # Make sure we emit an appropriate status when loading finished. While
# Qt has a bool "ok" attribute for loadFinished, it always is True when # Qt has a bool "ok" attribute for loadFinished, it always is True when
# using error pages... # using error pages...
# See https://github.com/The-Compiler/qutebrowser/issues/84 # See https://github.com/The-Compiler/qutebrowser/issues/84
frame.loadFinished.connect(lambda: frame.loadFinished.connect(lambda:
self.load_finished.emit( self._on_load_finished(
not self._widget.page().error_occurred)) not self._widget.page().error_occurred))
# Emit iconChanged with a QIcon like QWebEngineView does. # Emit iconChanged with a QIcon like QWebEngineView does.

View File

@ -43,10 +43,8 @@ class WebView(QWebView):
hintmanager: The HintManager instance for this view. hintmanager: The HintManager instance for this view.
scroll_pos: The current scroll position as (x%, y%) tuple. scroll_pos: The current scroll position as (x%, y%) tuple.
statusbar_message: The current javascript statusbar message. 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. win_id: The window ID of the view.
_tab_id: The tab 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. _old_scroll_pos: The old scroll position.
_check_insertmode: If True, in mouseReleaseEvent we should check if we _check_insertmode: If True, in mouseReleaseEvent we should check if we
need to enter/leave insert mode. need to enter/leave insert mode.
@ -58,7 +56,6 @@ class WebView(QWebView):
arg 1: x-position in %. arg 1: x-position in %.
arg 2: y-position in %. arg 2: y-position in %.
linkHovered: QWebPages linkHovered signal exposed. linkHovered: QWebPages linkHovered signal exposed.
load_status_changed: The loading status changed
url_text_changed: Current URL string changed. url_text_changed: Current URL string changed.
mouse_wheel_zoom: Emitted when the page should be zoomed because the mouse_wheel_zoom: Emitted when the page should be zoomed because the
mousewheel was used with ctrl. mousewheel was used with ctrl.
@ -68,7 +65,6 @@ class WebView(QWebView):
scroll_pos_changed = pyqtSignal(int, int) scroll_pos_changed = pyqtSignal(int, int)
linkHovered = pyqtSignal(str, str, str) linkHovered = pyqtSignal(str, str, str)
load_status_changed = pyqtSignal(str)
url_text_changed = pyqtSignal(str) url_text_changed = pyqtSignal(str)
shutting_down = pyqtSignal() shutting_down = pyqtSignal()
mouse_wheel_zoom = pyqtSignal(QPoint) mouse_wheel_zoom = pyqtSignal(QPoint)
@ -81,12 +77,10 @@ class WebView(QWebView):
self.setStyle(QStyleFactory.create('Fusion')) self.setStyle(QStyleFactory.create('Fusion'))
self.tab = tab self.tab = tab
self.win_id = win_id self.win_id = win_id
self.load_status = usertypes.LoadStatus.none
self._check_insertmode = False self._check_insertmode = False
self.scroll_pos = (-1, -1) self.scroll_pos = (-1, -1)
self.statusbar_message = '' self.statusbar_message = ''
self._old_scroll_pos = (-1, -1) self._old_scroll_pos = (-1, -1)
self._has_ssl_errors = False
self._ignore_wheel_event = False self._ignore_wheel_event = False
self._set_bg_color() self._set_bg_color()
self.cur_url = QUrl() self.cur_url = QUrl()
@ -126,14 +120,11 @@ class WebView(QWebView):
page = webpage.BrowserPage(self.win_id, self._tab_id, self) page = webpage.BrowserPage(self.win_id, self._tab_id, self)
self.setPage(page) self.setPage(page)
page.linkHovered.connect(self.linkHovered) page.linkHovered.connect(self.linkHovered)
page.mainFrame().loadStarted.connect(self.on_load_started)
page.mainFrame().loadFinished.connect(self.on_load_finished) page.mainFrame().loadFinished.connect(self.on_load_finished)
page.mainFrame().initialLayoutCompleted.connect( page.mainFrame().initialLayoutCompleted.connect(
self.on_initial_layout_completed) self.on_initial_layout_completed)
page.statusBarMessage.connect( page.statusBarMessage.connect(
lambda msg: setattr(self, 'statusbar_message', msg)) lambda msg: setattr(self, 'statusbar_message', msg))
page.networkAccessManager().sslErrors.connect(
lambda *args: setattr(self, '_has_ssl_errors', True))
return page return page
def __repr__(self): def __repr__(self):
@ -153,14 +144,6 @@ class WebView(QWebView):
# deleted # deleted
pass 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): def _set_bg_color(self):
"""Set the webpage background color as configured.""" """Set the webpage background color as configured."""
col = config.get('colors', 'webpage.bg') col = config.get('colors', 'webpage.bg')
@ -349,12 +332,6 @@ class WebView(QWebView):
self.setFocus() self.setFocus()
QApplication.postEvent(self, evt) 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() @pyqtSlot()
def on_load_finished(self): def on_load_finished(self):
"""Handle a finished page load. """Handle a finished page load.
@ -364,16 +341,6 @@ class WebView(QWebView):
See https://github.com/The-Compiler/qutebrowser/issues/84 See https://github.com/The-Compiler/qutebrowser/issues/84
""" """
ok = not self.page().error_occurred 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(): if not self.title():
self.titleChanged.emit(self.url().toDisplayString()) self.titleChanged.emit(self.url().toDisplayString())
self._handle_auto_insert_mode(ok) self._handle_auto_insert_mode(ok)