diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 22ec7ab38..6d4ceacbc 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -154,6 +154,9 @@ class Application(QApplication): config.init(self._args) log.init.debug("Initializing crashlog...") self._handle_segfault() + log.init.debug("Initializing js-bridge...") + js_bridge = qutescheme.JSBridge(self) + objreg.register('js-bridge', js_bridge) log.init.debug("Initializing websettings...") websettings.init() log.init.debug("Initializing adblock...") diff --git a/qutebrowser/html/settings.html b/qutebrowser/html/settings.html new file mode 100644 index 000000000..2bf6c6fc2 --- /dev/null +++ b/qutebrowser/html/settings.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block script %} +var win_id = {{ win_id }}; +var cset = function(section, option, el) { + value = el.value; + window.qute.set(win_id, section, option, value); +} +{% endblock %} + +{% block style %} +table { border: 1px solid grey; border-collapse: collapse; } +pre { margin: 2px; } +th, td { border: 1px solid grey; padding: 0px 5px; } +th { background: lightgrey; } +th pre { color: grey; text-align: left; } +{% endblock %} + +{% block content %} + +

{{ title }}

+ +{% for section in config.DATA %} + + {% for d, e in config.DATA.get(section).items() %} + + + + + {% endfor %} +{% endfor %} +

{{ section }}

{{ config.SECTION_DESC.get(section)|wordwrap(width=120) }}
{{ d }} (Current: {{ e.value()|truncate(100) }}) + + +
+ +{% endblock %} diff --git a/qutebrowser/network/qutescheme.py b/qutebrowser/network/qutescheme.py index a9695be8e..a0c0a08ea 100644 --- a/qutebrowser/network/qutescheme.py +++ b/qutebrowser/network/qutescheme.py @@ -27,11 +27,14 @@ Module attributes: pyeval_output: The output of the last :pyeval command. """ +from PyQt5.QtCore import pyqtSlot, QObject from PyQt5.QtNetwork import QNetworkReply import qutebrowser from qutebrowser.network import schemehandler, networkreply -from qutebrowser.utils import version, utils, jinja, log, message, docutils +from qutebrowser.utils import (version, utils, jinja, log, message, docutils, + objreg) +from qutebrowser.config import configtypes pyeval_output = ":pyeval was never called" @@ -78,6 +81,22 @@ class QuteSchemeHandler(schemehandler.SchemeHandler): request, data, 'text/html', self.parent()) +class JSBridge(QObject): + + """Javascript-bridge for special qute:... pages.""" + + def __init__(self, parent=None): + super().__init__(parent) + + @pyqtSlot(int, str, str, str) + def set(self, win_id, sectname, optname, value): + """Slot to set a setting from qute:settings.""" + try: + objreg.get('config').set('conf', sectname, optname, value) + except configtypes.ValidationError as e: + message.error(win_id, e) + + def qute_pyeval(_win_id, _request): """Handler for qute:pyeval. Return HTML content as bytes.""" html = jinja.env.get_template('pre.html').render( @@ -146,6 +165,15 @@ def qute_help(win_id, request): return utils.read_file(path).encode('UTF-8', errors='xmlcharrefreplace') +def qute_settings(win_id, request): + """Handler for qute:settings. View/change qute configuration""" + from qutebrowser.config import configdata + + html = jinja.env.get_template('settings.html').render( + win_id=win_id, title='settings', config=configdata) + return html.encode('UTF-8', errors='xmlcharrefreplace') + + HANDLERS = { 'pyeval': qute_pyeval, 'version': qute_version, @@ -153,4 +181,5 @@ HANDLERS = { 'log': qute_log, 'gpl': qute_gpl, 'help': qute_help, + 'settings': qute_settings, } diff --git a/qutebrowser/widgets/webview.py b/qutebrowser/widgets/webview.py index 9530ae1a6..abc52c257 100644 --- a/qutebrowser/widgets/webview.py +++ b/qutebrowser/widgets/webview.py @@ -289,9 +289,6 @@ class WebView(QWebView): Args: url: The URL to load as QUrl - - Return: - Return status of self.load """ qtutils.ensure_valid(url) urlstr = url.toDisplayString() @@ -299,7 +296,20 @@ class WebView(QWebView): self.titleChanged.emit(urlstr) self.cur_url = url self.url_text_changed.emit(url.toDisplayString()) - return self.load(url) + self.load(url) + if url.scheme() == 'qute': + frame = self.page().mainFrame() + frame.javaScriptWindowObjectCleared.connect(self.add_js_bridge) + + def add_js_bridge(self): + """Add the javascript bridge for qute:... pages.""" + frame = self.sender() + assert frame.url().scheme() == 'qute' + bridge = objreg.get('js-bridge') + frame.addToJavaScriptWindowObject('qute', bridge) + # We need to make sure the bridge doesn't get added on non-qute:... + # pages. + frame.javaScriptWindowObjectCleared.disconnect(self.add_js_bridge) def zoom_perc(self, perc, fuzzyval=True): """Zoom to a given zoom percentage.