From edb65ecf5011c8654744d4cfd89dc78ac5bb00ed Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 14 Jun 2016 18:47:26 +0200 Subject: [PATCH] Add run_js_eval and get :jseval to run --- qutebrowser/browser/commands.py | 41 ++++++++++--------- qutebrowser/browser/tab.py | 8 ++++ qutebrowser/browser/webengine/webenginetab.py | 6 +++ qutebrowser/browser/webkit/webkittab.py | 5 +++ 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 36fb99ee5..6618aa731 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1107,7 +1107,7 @@ class CommandDispatcher: QWebSettings.JavascriptEnabled): if tab: page.open_target = usertypes.ClickTarget.tab - page.currentFrame().evaluateJavaScript( + widget.run_js_async( 'window.getSelection().anchorNode.parentNode.click()') else: try: @@ -1698,26 +1698,29 @@ class CommandDispatcher: js_code: The string to evaluate. quiet: Don't show resulting JS object. """ - frame = self._current_widget().page().mainFrame() - out = frame.evaluateJavaScript(js_code) - if quiet: - return - - if out is None: - # Getting the actual error (if any) seems to be difficult. The - # error does end up in BrowserPage.javaScriptConsoleMessage(), but - # distinguishing between :jseval errors and errors from the webpage - # is not trivial... - message.info(self._win_id, 'No output or error') + jseval_cb = None else: - # The output can be a string, number, dict, array, etc. But *don't* - # output too much data, as this will make qutebrowser hang - out = str(out) - if len(out) > 5000: - message.info(self._win_id, out[:5000] + ' [...trimmed...]') - else: - message.info(self._win_id, out) + def jseval_cb(out): + if out is None: + # Getting the actual error (if any) seems to be difficult. + # The error does end up in + # BrowserPage.javaScriptConsoleMessage(), but distinguishing + # between :jseval errors and errors from the webpage is not + # trivial... + message.info(self._win_id, 'No output or error') + else: + # The output can be a string, number, dict, array, etc. But + # *don't* output too much data, as this will make + # qutebrowser hang + out = str(out) + if len(out) > 5000: + message.info(self._win_id, out[:5000] + ' [...trimmed...]') + else: + message.info(self._win_id, out) + + self._current_widget().run_js_async(js_code, callback=jseval_cb) + @cmdutils.register(instance='command-dispatcher', scope='window') def fake_key(self, keystring, global_=False): diff --git a/qutebrowser/browser/tab.py b/qutebrowser/browser/tab.py index d9c6773aa..ad18de580 100644 --- a/qutebrowser/browser/tab.py +++ b/qutebrowser/browser/tab.py @@ -303,6 +303,14 @@ class AbstractTab(QWidget): """ raise NotImplementedError + def run_js_async(self, code, callback=None): + """Run javascript async. + + The given callback will be called with the result when running JS is + complete. + """ + raise NotImplementedError + def shutdown(self): raise NotImplementedError diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 231d2175b..7631e95eb 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -114,6 +114,12 @@ class WebEngineViewTab(tab.AbstractTab): else: self._widget.page().toHtml(callback) + def run_js_async(self, code, callback=None): + if callback is None: + self._widget.page().runJavaScript(code) + else: + self._widget.page().runJavaScript(code, callback) + def shutdown(self): # TODO pass diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index f19b7048e..6960302c4 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -378,6 +378,11 @@ class WebViewTab(tab.AbstractTab): else: callback(frame.toHtml()) + def run_js_async(self, code, callback=None): + result = self._widget.page().mainFrame().evaluateJavaScript(code) + if callback is not None: + callback(result) + def icon(self): return self._widget.icon()