diff --git a/TODO b/TODO
index f302550f6..96025f0d4 100644
--- a/TODO
+++ b/TODO
@@ -64,6 +64,8 @@ Other stuff
make sure webview.page() and page.mainFrame() never change
http://agateau.com/article-series/pyqtwebkit-experiments/
https://code.google.com/p/devicenzo/source/browse/trunk/devicenzo.py
+http://die-offenbachs.homelinux.org:48888/hg/eric5/file/5d937eb378dd/Helpviewer
+
Keybinding stuff (from dwb)
===========================
diff --git a/qutebrowser/html/error.html b/qutebrowser/html/error.html
new file mode 100644
index 000000000..1d8f5ed7b
--- /dev/null
+++ b/qutebrowser/html/error.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
Problem occurred while loading the URL {url}
+
{error}
+
+
+
+
+
+
+
diff --git a/qutebrowser/utils/misc.py b/qutebrowser/utils/misc.py
index e31b71002..948dfe4f0 100644
--- a/qutebrowser/utils/misc.py
+++ b/qutebrowser/utils/misc.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see .
+import os.path
+
from PyQt5.QtCore import pyqtRemoveInputHook
try:
@@ -39,3 +41,12 @@ def set_trace():
print("before executing c(ontinue).")
pyqtRemoveInputHook()
return pdb_set_trace()
+
+
+def read_file(filename):
+ """Return the contents of a file contained with qutebrowser."""
+ fn = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+ os.path.pardir, filename)
+ with open(fn, 'r') as f:
+ # FIXME is there a nicer way?
+ return '\n'.join(f.readlines())
diff --git a/qutebrowser/widgets/browser.py b/qutebrowser/widgets/browser.py
index d40adc0e2..89f427de2 100644
--- a/qutebrowser/widgets/browser.py
+++ b/qutebrowser/widgets/browser.py
@@ -25,16 +25,19 @@ containing BrowserTabs).
import logging
import functools
+import sip
from PyQt5.QtWidgets import QShortcut, QApplication, QSizePolicy
from PyQt5.QtCore import pyqtSignal, Qt, QEvent
from PyQt5.QtGui import QClipboard
from PyQt5.QtPrintSupport import QPrintPreviewDialog
+from PyQt5.QtNetwork import QNetworkReply
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
import qutebrowser.utils.about as about
import qutebrowser.utils.url as urlutils
from qutebrowser.widgets.tabbar import TabWidget
from qutebrowser.utils.signals import dbg_signal, SignalCache
+from qutebrowser.utils.misc import read_file
class TabbedBrowser(TabWidget):
@@ -437,6 +440,7 @@ class BrowserTab(QWebView):
def __init__(self, parent=None):
super().__init__(parent)
+ self.setPage(BrowserPage())
self.signal_cache = SignalCache(uncached=['linkHovered'])
self.loadProgress.connect(self.set_progress)
self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
@@ -533,3 +537,47 @@ class BrowserTab(QWebView):
self._open_new_tab = (e.button() == Qt.MidButton or
e.modifiers() & Qt.ControlModifier)
return super().event(e)
+
+
+class BrowserPage(QWebPage):
+
+ """Our own QWebPage with advanced features."""
+
+ _extension_handlers = None
+
+ def __init__(self):
+ super().__init__()
+ self._extension_handlers = {
+ QWebPage.ErrorPageExtension: self._handle_errorpage,
+ }
+
+ def supportsExtension(self, ext):
+ """Override QWebPage::supportsExtension to provide error pages."""
+ return ext in self._extension_handlers
+
+ def extension(self, ext, opt, out):
+ """Override QWebPage::extension to provide error pages."""
+ try:
+ handler = self._extension_handlers[ext]
+ except KeyError:
+ return super().extension(ext, opt, out)
+ return handler(opt, out)
+
+ def _handle_errorpage(self, opt, out):
+ """Display an error page if needed.
+
+ Loosly based on Helpviewer/HelpBrowserWV.py from eric5
+ (line 260 @ 5d937eb378dd)
+
+ """
+ info = sip.cast(opt, QWebPage.ErrorPageExtensionOption)
+ errpage = sip.cast(out, QWebPage.ErrorPageExtensionReturn)
+ errpage.baseUrl = info.url
+ if (info.domain == QWebPage.QtNetwork and
+ info.error == QNetworkReply.OperationCanceledError):
+ return False
+ urlstr = urlutils.urlstring(info.url)
+ title = "Error loading page: {}".format(urlstr)
+ errpage.content = read_file('html/error.html').format(
+ title=title, url=urlstr, error=info.errorString)
+ return True