Merge branch 'Carpetsmoker-jseval'
This commit is contained in:
commit
d2e103ecc1
@ -41,6 +41,7 @@ Added
|
||||
- New setting `colors -> webpage.bg` to set the background color to use for websites which don't set one.
|
||||
- New (hidden) command `:clear-keychain` to clear a partially entered keychain (bound to `<Escape>` by default, in addition to clearing search).
|
||||
- Many new color settings (foreground setting for every background setting).
|
||||
- New command `:jseval` to run a javascript snippet on the current page.
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
@ -138,8 +138,8 @@ Contributors, sorted by the number of commits in descending order:
|
||||
* Raphael Pierzina
|
||||
* Joel Torstensson
|
||||
* Claude
|
||||
* Lamar Pavel
|
||||
* Martin Tournoij
|
||||
* Lamar Pavel
|
||||
* Austin Anderson
|
||||
* Artur Shaik
|
||||
* Antoni Boucher
|
||||
|
@ -20,6 +20,7 @@
|
||||
|<<hint,hint>>|Start hinting.
|
||||
|<<home,home>>|Open main startpage in current tab.
|
||||
|<<inspector,inspector>>|Toggle the web inspector.
|
||||
|<<jseval,jseval>>|Evaluate a JavaScript string.
|
||||
|<<later,later>>|Execute a command after some time.
|
||||
|<<navigate,navigate>>|Open typical prev/next links or navigate using the URL path.
|
||||
|<<open,open>>|Open a URL in the current/[count]th tab.
|
||||
@ -241,6 +242,22 @@ Open main startpage in current tab.
|
||||
=== inspector
|
||||
Toggle the web inspector.
|
||||
|
||||
[[jseval]]
|
||||
=== jseval
|
||||
Syntax: +:jseval [*--quiet*] 'js-code'+
|
||||
|
||||
Evaluate a JavaScript string.
|
||||
|
||||
==== positional arguments
|
||||
* +'js-code'+: The string to evaluate.
|
||||
|
||||
==== optional arguments
|
||||
* +*-q*+, +*--quiet*+: Don't show resulting JS object.
|
||||
|
||||
==== 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'+
|
||||
|
@ -1563,3 +1563,33 @@ 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, quiet=False):
|
||||
"""Evaluate a JavaScript string.
|
||||
|
||||
Args:
|
||||
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')
|
||||
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)
|
||||
|
@ -29,6 +29,11 @@ from qutebrowser.utils import log, utils, message, docutils, objreg, usertypes
|
||||
from qutebrowser.utils import debug as debug_utils
|
||||
|
||||
|
||||
def arg_name(name):
|
||||
"""Get the name an argument should have based on its Python name."""
|
||||
return name.rstrip('_').replace('_', '-')
|
||||
|
||||
|
||||
class Command:
|
||||
|
||||
"""Base skeleton for a command.
|
||||
@ -288,7 +293,7 @@ class Command:
|
||||
A list of args.
|
||||
"""
|
||||
args = []
|
||||
name = param.name.rstrip('_').replace('_', '-')
|
||||
name = arg_name(param.name)
|
||||
shortname = annotation_info.flag or name[0]
|
||||
if len(shortname) != 1:
|
||||
raise ValueError("Flag '{}' of parameter {} (command {}) must be "
|
||||
@ -304,7 +309,7 @@ class Command:
|
||||
if typ is not bool:
|
||||
self.flags_with_args += [short_flag, long_flag]
|
||||
else:
|
||||
args.append(name)
|
||||
args.append(param.name)
|
||||
if not annotation_info.hide:
|
||||
self.pos_args.append((param.name, name))
|
||||
return args
|
||||
@ -408,17 +413,16 @@ class Command:
|
||||
raise TypeError("{}: invalid parameter type {} for argument "
|
||||
"{!r}!".format(self.name, param.kind, param.name))
|
||||
|
||||
def _get_param_name_and_value(self, param):
|
||||
"""Get the converted name and value for an inspect.Parameter."""
|
||||
name = param.name.rstrip('_')
|
||||
value = getattr(self.namespace, name)
|
||||
def _get_param_value(self, param):
|
||||
"""Get the converted value for an inspect.Parameter."""
|
||||
value = getattr(self.namespace, param.name)
|
||||
if param.name in self._type_conv:
|
||||
# We convert enum types after getting the values from
|
||||
# argparse, because argparse's choices argument is
|
||||
# processed after type conversation, which is not what we
|
||||
# want.
|
||||
value = self._type_conv[param.name](value)
|
||||
return name, value
|
||||
return value
|
||||
|
||||
def _get_call_args(self, win_id):
|
||||
"""Get arguments for a function call.
|
||||
@ -452,14 +456,14 @@ class Command:
|
||||
# Special case for win_id parameter.
|
||||
self._get_win_id_arg(win_id, param, args, kwargs)
|
||||
continue
|
||||
name, value = self._get_param_name_and_value(param)
|
||||
value = self._get_param_value(param)
|
||||
if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
|
||||
args.append(value)
|
||||
elif param.kind == inspect.Parameter.VAR_POSITIONAL:
|
||||
if value is not None:
|
||||
args += value
|
||||
elif param.kind == inspect.Parameter.KEYWORD_ONLY:
|
||||
kwargs[name] = value
|
||||
kwargs[param.name] = value
|
||||
else:
|
||||
raise TypeError("{}: Invalid parameter type {} for argument "
|
||||
"'{}'!".format(
|
||||
|
@ -37,7 +37,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
import qutebrowser.app
|
||||
from scripts import asciidoc2html, utils
|
||||
from qutebrowser import qutebrowser
|
||||
from qutebrowser.commands import cmdutils
|
||||
from qutebrowser.commands import cmdutils, command
|
||||
from qutebrowser.config import configdata
|
||||
from qutebrowser.utils import docutils
|
||||
|
||||
@ -54,6 +54,14 @@ class UsageFormatter(argparse.HelpFormatter):
|
||||
"""Override _format_usage to not add the 'usage:' prefix."""
|
||||
return super()._format_usage(usage, actions, groups, '')
|
||||
|
||||
def _get_default_metavar_for_optional(self, action):
|
||||
"""Do name transforming when getting metavar."""
|
||||
return command.arg_name(action.dest.upper())
|
||||
|
||||
def _get_default_metavar_for_positional(self, action):
|
||||
"""Do name transforming when getting metavar."""
|
||||
return command.arg_name(action.dest)
|
||||
|
||||
def _metavar_formatter(self, action, default_metavar):
|
||||
"""Override _metavar_formatter to add asciidoc markup to metavars.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user