diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 5827a8909..9e387f42e 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 41835d53b..9ff65e7bc 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1563,3 +1563,29 @@ class CommandDispatcher: view = self._current_widget() for _ in range(count): view.triggerPageAction(member) + + @cmdutils.register(instance='command-dispatcher', scope='window', + maxsplit=0, no_cmd_split=True) + def jseval(self, js_code): + """Evaluate a JavaScript string. + + Args: + js_code: The string to evaluate. + """ + out = self._current_widget().page().mainFrame().evaluateJavaScript( + js_code) + + 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)