diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index c33bccaaf..287620867 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -20,6 +20,7 @@ |<>|Start hinting. |<>|Open main startpage in current tab. |<>|Toggle the web inspector. +|<>|Evaluate a JavaScript string. |<>|Execute a command after some time. |<>|Open typical prev/next links or navigate using the URL path. |<>|Open a URL in the current/[count]th tab. @@ -241,6 +242,19 @@ Open main startpage in current tab. === inspector Toggle the web inspector. +[[jseval]] +=== jseval +Syntax: +:jseval 'js_code'+ + +Evaluate a JavaScript string. + +==== positional arguments +* +'js_code'+: The string to evaluate. + +==== note +* This command does not split arguments after the last argument and handles quotes literally. +* With this command, +;;+ is interpreted literally instead of splitting off a second command. + [[later]] === later Syntax: +:later 'ms' 'command'+ diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index bc2159843..aa8430127 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1513,20 +1513,28 @@ class CommandDispatcher: @cmdutils.register(instance='command-dispatcher', scope='window', maxsplit=0, no_cmd_split=True) - def jseval(self, js): + def jseval(self, js_code): """Evaluate a JavaScript string. Args: - s: The string to evaluate. + js_code: The string to evaluate. """ tabbed_browser = objreg.get('tabbed-browser', scope='window', window='last-focused') - out = tabbed_browser.widget(0).page().mainFrame().evaluateJavaScript( - 'window.__qute_jseval__ = true;\n' + js) + frame = tabbed_browser.widget(0).page().mainFrame() + out = frame.evaluateJavaScript(js_code) - if out is not None: - message.info(self._win_id, out) - elif tabbed_browser.widget(0).page().jseval_error: - message.error(self._win_id, - tabbed_browser.widget(0).page().jseval_error) - tabbed_browser.widget(0).page().jseval_error = None + 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) diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index 9e49032df..005a6e300 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -63,7 +63,6 @@ class BrowserPage(QWebPage): def __init__(self, win_id, tab_id, parent=None): super().__init__(parent) self._win_id = win_id - self.jseval_error = None self._is_shutting_down = False self._extension_handlers = { QWebPage.ErrorPageExtension: self._handle_errorpage, @@ -498,16 +497,6 @@ class BrowserPage(QWebPage): def javaScriptConsoleMessage(self, msg, line, source): """Override javaScriptConsoleMessage to use debug log.""" - - jseval = self.mainFrame().evaluateJavaScript('window.__qute_jseval__') - if jseval: - self.mainFrame().evaluateJavaScript('window.__qute_jseval__ = undefined;') - if source == 'undefined' and jseval: - self.mainFrame().evaluateJavaScript('window.__qute_jseval__ = false;') - print('jseval errror ->', jseval) - self.jseval_error = 'Error on line {}: {}'.format(line, msg) - print('other js error ->', msg, line, source) - if config.get('general', 'log-javascript-console'): log.js.debug("[{}:{}] {}".format(source, line, msg))