From 9cfb4b34316e20c0fd6d65fd576073facd036db7 Mon Sep 17 00:00:00 2001 From: Brian Jackson Date: Tue, 25 Nov 2014 14:29:20 -0600 Subject: [PATCH] Fix problem with qutesettings scope in pages Fix to make sure the js bridge code is only enabled when qute: pages are shown. Previously it would only be available to the first page (and before that it was available to all pages). --- qutebrowser/app.py | 3 +++ qutebrowser/config/config.py | 7 ------- qutebrowser/html/settings.html | 5 +++-- qutebrowser/network/qutescheme.py | 24 +++++++++++++++++++----- qutebrowser/widgets/webview.py | 18 ++++++++++++++---- 5 files changed, 39 insertions(+), 18 deletions(-) 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/config/config.py b/qutebrowser/config/config.py index bb8b2b2ea..4a27a8073 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -520,13 +520,6 @@ class ConfigManager(QObject): if self._initialized: self._after_set(sectname, optname) - @pyqtSlot(int, str, str, str) - def set_javascript(self, win_id, sectname, optname, value): - try: - self.set('conf', sectname, optname, value) - except configtypes.ValidationError as e: - message.error(win_id, e) - @cmdutils.register(instance='config') def save(self): """Save the config file.""" diff --git a/qutebrowser/html/settings.html b/qutebrowser/html/settings.html index 38449ad95..2bf6c6fc2 100644 --- a/qutebrowser/html/settings.html +++ b/qutebrowser/html/settings.html @@ -4,7 +4,7 @@ var win_id = {{ win_id }}; var cset = function(section, option, el) { value = el.value; - window.qutesettings.set_javascript(win_id, section, option, value); + window.qute.set(win_id, section, option, value); } {% endblock %} @@ -17,6 +17,7 @@ th pre { color: grey; text-align: left; } {% endblock %} {% block content %} +

{{ title }}

{% for section in config.DATA %} @@ -35,4 +36,4 @@ th pre { color: grey; text-align: left; } {% endfor %}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/qutebrowser/network/qutescheme.py b/qutebrowser/network/qutescheme.py index e29f4631d..a0c0a08ea 100644 --- a/qutebrowser/network/qutescheme.py +++ b/qutebrowser/network/qutescheme.py @@ -27,12 +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, objreg) +from qutebrowser.config import configtypes pyeval_output = ":pyeval was never called" @@ -79,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( @@ -151,12 +169,8 @@ def qute_settings(win_id, request): """Handler for qute:settings. View/change qute configuration""" from qutebrowser.config import configdata - cfg = objreg.get('config') - frame = objreg.get('webview', scope='tab').page().mainFrame() - frame.addToJavaScriptWindowObject("qutesettings", cfg) - html = jinja.env.get_template('settings.html').render( - win_id=win_id, title='settings', config=configdata, cfg=cfg) + win_id=win_id, title='settings', config=configdata) return html.encode('UTF-8', errors='xmlcharrefreplace') 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.