From 5b1cca92ab199798337d873f8a708df7acebe12a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 13 Jul 2016 13:46:47 +0200 Subject: [PATCH] Add run_js_blocking to tab API --- qutebrowser/browser/browsertab.py | 8 ++++++++ qutebrowser/browser/webengine/webenginetab.py | 15 +++++++++++++++ qutebrowser/browser/webkit/webkittab.py | 5 ++++- tests/unit/browser/test_tab.py | 6 ++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index f034f4755..30979d255 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -611,6 +611,14 @@ class AbstractTab(QWidget): """ raise NotImplementedError + def run_js_blocking(self, code): + """Run javascript and block. + + This returns the result to the caller. Its use should be avoided when + possible as it runs a local event loop for QtWebEngine. + """ + raise NotImplementedError + def shutdown(self): raise NotImplementedError diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 147f7be0f..c540f2f1d 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -343,6 +343,21 @@ class WebEngineTab(browsertab.AbstractTab): else: self._widget.page().runJavaScript(code, callback) + def run_js_blocking(self, code): + loop = qtutils.EventLoop() + js_ret = None + + def js_cb(val): + nonlocal js_ret + js_ret = val + loop.quit() + + self.run_js_async(code, js_cb) + loop.exec_() # blocks until loop.quit() in js_cb + assert js_ret is not None + + return js_ret + def shutdown(self): log.stub() diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index 26a3dd663..f5ab2d7b9 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -525,10 +525,13 @@ class WebKitTab(browsertab.AbstractTab): callback(frame.toHtml()) def run_js_async(self, code, callback=None): - result = self._widget.page().mainFrame().evaluateJavaScript(code) + result = self.run_js_blocking(code) if callback is not None: callback(result) + def run_js_blocking(self, code): + return self._widget.page().mainFrame().evaluateJavaScript(code) + def icon(self): return self._widget.icon() diff --git a/tests/unit/browser/test_tab.py b/tests/unit/browser/test_tab.py index a4cc50c91..9500e7f39 100644 --- a/tests/unit/browser/test_tab.py +++ b/tests/unit/browser/test_tab.py @@ -121,6 +121,12 @@ def test_tab(qtbot, view, config_stub, tab_registry): assert view.parent() is tab_w +class TestJs: + + def test_blocking(self, tab): + assert tab.run_js_blocking('1 + 1') == 2 + + class TestTabData: def test_known_attr(self):