From a0437a3e683fa81e271be88c907e25143d0e467c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 12 Dec 2018 08:10:28 +0100 Subject: [PATCH] Improve Sphinx docs --- doc/extapi/api.rst | 48 +++++++++++ doc/extapi/index.rst | 48 +---------- doc/extapi/tab.rst | 44 +++++++++++ qutebrowser/api/cmdutils.py | 97 ++++++++++++++++++----- qutebrowser/api/config.py | 10 +++ qutebrowser/api/downloads.py | 15 ++++ qutebrowser/api/hook.py | 37 ++++++++- qutebrowser/api/interceptor.py | 10 ++- qutebrowser/browser/browsertab.py | 105 +++++++++++-------------- qutebrowser/browser/webelem.py | 13 +-- qutebrowser/extensions/interceptors.py | 4 + qutebrowser/utils/message.py | 20 ++--- qutebrowser/utils/usertypes.py | 42 +++++++--- 13 files changed, 337 insertions(+), 156 deletions(-) create mode 100644 doc/extapi/api.rst create mode 100644 doc/extapi/tab.rst diff --git a/doc/extapi/api.rst b/doc/extapi/api.rst new file mode 100644 index 000000000..b63db57c3 --- /dev/null +++ b/doc/extapi/api.rst @@ -0,0 +1,48 @@ +API modules +=========== + +cmdutils module +--------------- + +.. automodule:: qutebrowser.api.cmdutils + :members: + :imported-members: + +apitypes module +--------------- + +.. automodule:: qutebrowser.api.apitypes + :members: + :imported-members: + +config module +------------- + +.. automodule:: qutebrowser.api.config + :members: + +downloads module +---------------- + +.. automodule:: qutebrowser.api.downloads + :members: + +hook module +----------- + +.. automodule:: qutebrowser.api.hook + :members: + +interceptor module +------------------ + +.. automodule:: qutebrowser.api.interceptor + :members: + :imported-members: + +message module +-------------- + +.. automodule:: qutebrowser.api.message + :members: + :imported-members: diff --git a/doc/extapi/index.rst b/doc/extapi/index.rst index e176e3a0d..d181c2ccd 100644 --- a/doc/extapi/index.rst +++ b/doc/extapi/index.rst @@ -10,53 +10,9 @@ Welcome to qutebrowser extensions's documentation! :maxdepth: 2 :caption: Contents: -cmdutils module ---------------- + api + tab -.. automodule:: qutebrowser.api.cmdutils - :members: - -.. FIXME: What about imported things? - -apitypes module ---------------- - -.. automodule:: qutebrowser.api.apitypes - :members: - :imported-members: - -config module -------------- - -.. automodule:: qutebrowser.api.config - :members: - -downloads module ----------------- - -.. automodule:: qutebrowser.api.downloads - :members: - -hook module ------------ - -.. automodule:: qutebrowser.api.hook - :members: - -interceptor module ------------------- - -.. automodule:: qutebrowser.api.interceptor - :members: - -.. FIXME: What about imported things? - -message module --------------- - -.. automodule:: qutebrowser.api.message - :members: - :imported-members: Indices and tables ================== diff --git a/doc/extapi/tab.rst b/doc/extapi/tab.rst new file mode 100644 index 000000000..57a14ac6e --- /dev/null +++ b/doc/extapi/tab.rst @@ -0,0 +1,44 @@ +Tab API +======= + +.. autoclass:: qutebrowser.browser.browsertab.AbstractTab() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractAction() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractPrinting() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractSearch() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractZoom() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractCaret() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractScroller() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractHistory() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractElements() + :members: + +.. autoclass:: qutebrowser.browser.browsertab.AbstractAudio() + :members: + +Web element API +=============== + +.. autoclass:: qutebrowser.browser.webelem.AbstractWebElement + :members: + +.. autoclass:: qutebrowser.browser.webelem.Error + :members: + +.. autoclass:: qutebrowser.browser.webelem.OrphanedError + :members: diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py index 093244727..f6a6f6da9 100644 --- a/qutebrowser/api/cmdutils.py +++ b/qutebrowser/api/cmdutils.py @@ -17,7 +17,38 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Utilities for command handlers.""" +""" +qutebrowser has the concept of functions which are exposed to the user as +commands. + +Creating a new command is straightforward:: + + from qutebrowser.api import cmdutils + + @cmdutils.register(...) + def foo(): + ... + +The commands arguments are automatically deduced by inspecting your function. + +The types of the function arguments are inferred based on their default values, +e.g., an argument `foo=True` will be converted to a flag `-f`/`--foo` in +qutebrowser's commandline. + +The type can be overridden using Python's function annotations:: + + @cmdutils.register(...) + def foo(bar: int, baz=True): + ... + +Possible values: + +- A callable (``int``, ``float``, etc.): Gets called to validate/convert the value. +- A python enum type: All members of the enum are possible values. +- A ``typing.Union`` of multiple types above: Any of these types are valid + values, e.g., ``typing.Union[str, int]``. +""" + import inspect import typing @@ -33,15 +64,17 @@ class CommandError(cmdexc.Error): """Raised when a command encounters an error while running. If your command handler encounters an error and cannot continue, raise this - exception with an appropriate error message: + exception with an appropriate error message:: raise cmdexc.CommandError("Message") The message will then be shown in the qutebrowser status bar. - Note that you should only raise this exception while a command handler is - run. Raising it at another point causes qutebrowser to crash due to an - unhandled exception. + .. note:: + + You should only raise this exception while a command handler is run. + Raising it at another point causes qutebrowser to crash due to an + unhandled exception. """ @@ -76,13 +109,7 @@ def check_exclusive(flags: typing.Iterable[bool], class register: # noqa: N801,N806 pylint: disable=invalid-name - """Decorator to register a new command handler. - - Attributes: - _instance: The object from the object registry to be used as "self". - _name: The name (as string) or names (as list) of the command. - _kwargs: The arguments to pass to Command. - """ + """Decorator to register a new command handler.""" def __init__(self, *, instance: str = None, @@ -95,8 +122,11 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name Args: See class attributes. """ + # The object from the object registry to be used as "self". self._instance = instance + # The name (as string) or names (as list) of the command. self._name = name + # The arguments to pass to Command. self._kwargs = kwargs def __call__(self, func: typing.Callable) -> typing.Callable: @@ -127,16 +157,47 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name class argument: # noqa: N801,N806 pylint: disable=invalid-name - """Decorator to customize an argument for @cmdutils.register. + """Decorator to customize an argument. - Attributes: - _argname: The name of the argument to handle. - _kwargs: Keyword arguments, valid ArgInfo members + You can customize how an argument is handled using the ``@cmdutils.argument`` + decorator *after* ``@cmdutils.register``. This can, for example, be used to + customize the flag an argument should get:: + + @cmdutils.register(...) + @cmdutils.argument('bar', flag='c') + def foo(bar): + ... + + For a ``str`` argument, you can restrict the allowed strings using ``choices``:: + + @cmdutils.register(...) + @cmdutils.argument('bar', choices=['val1', 'val2']) + def foo(bar: str): + ... + + For ``typing.Union`` types, the given ``choices`` are only checked if other types + (like ``int``) don't match. + + The following arguments are supported for ``@cmdutils.argument``: + + - ``flag``: Customize the short flag (``-x``) the argument will get. + - ``value``: Tell qutebrowser to fill the argument with special values: + + * ``value=cmdutils.Value.count``: The ``count`` given by the user to the command. + * ``value=cmdutils.Value.win_id``: The window ID of the current window. + * ``value=cmdutils.Value.cur_tab``: The tab object which is currently focused. + + - ``completion``: A completion function to use when completing arguments for + the given command. + - ``choices``: The allowed string choices for the argument. + + The name of an argument will always be the parameter name, with any trailing + underscores stripped and underscores replaced by dashes. """ def __init__(self, argname: str, **kwargs: typing.Any) -> None: - self._argname = argname - self._kwargs = kwargs + self._argname = argname # The name of the argument to handle. + self._kwargs = kwargs # Valid ArgInfo members. def __call__(self, func: typing.Callable) -> typing.Callable: funcname = func.__name__ diff --git a/qutebrowser/api/config.py b/qutebrowser/api/config.py index 4a5d73936..0c633e54d 100644 --- a/qutebrowser/api/config.py +++ b/qutebrowser/api/config.py @@ -25,6 +25,16 @@ from PyQt5.QtCore import QUrl from qutebrowser.config import config +#: Simplified access to config values using attribute acccess. +#: For example, to access the ``content.javascript.enabled`` setting, +#: you can do:: +#: +#: if config.val.content.javascript.enabled: +#: ... +#: +#: This also supports setting configuration values:: +#: +#: config.val.content.javascript.enabled = False val = typing.cast('config.ConfigContainer', None) diff --git a/qutebrowser/api/downloads.py b/qutebrowser/api/downloads.py index 82c68d0bd..a2a37d931 100644 --- a/qutebrowser/api/downloads.py +++ b/qutebrowser/api/downloads.py @@ -52,6 +52,21 @@ def download_temp(url: QUrl) -> TempDownload: """Download the given URL into a file object. The download is not saved to disk. + + Returns a ``TempDownload`` object, which triggers a ``finished`` signal + when the download has finished:: + + dl = downloads.download_temp(QUrl("https://www.example.com/")) + dl.finished.connect(functools.partial(on_download_finished, dl)) + + After the download has finished, its ``successful`` attribute can be + checked to make sure it finished successfully. If so, its contents can be + read by accessing the ``fileobj`` attribute:: + + def on_download_finished(download: downloads.TempDownload) -> None: + if download.successful: + print(download.fileobj.read()) + download.fileobj.close() """ fobj = io.BytesIO() fobj.name = 'temporary: ' + url.host() diff --git a/qutebrowser/api/hook.py b/qutebrowser/api/hook.py index 3f06121da..84e103cbd 100644 --- a/qutebrowser/api/hook.py +++ b/qutebrowser/api/hook.py @@ -36,7 +36,17 @@ def _add_module_info(func: typing.Callable) -> loader.ModuleInfo: class init: - """Decorator to mark a function to run when initializing.""" + """Decorator to mark a function to run when initializing. + + The decorated function gets called with a + :class:`qutebrowser.api.apitypes.InitContext` as argument. + + Example:: + + @hook.init() + def init(_context): + message.info("Extension initialized.") + """ def __call__(self, func: typing.Callable) -> typing.Callable: info = _add_module_info(func) @@ -48,7 +58,30 @@ class init: class config_changed: - """Decorator to get notified about changed configs.""" + """Decorator to get notified about changed configs. + + By default, the decorated function is called when any change in the config + occurs:: + + @hook.config_changed() + def on_config_changed(): + ... + + When an option name is passed, it's only called when the given option was + changed:: + + @hook.config_changed('content.javascript.enabled') + def on_config_changed(): + ... + + Alternatively, a part of an option name can be specified. In the following + snippet, ``on_config_changed`` gets called when either + ``bindings.commands`` or ``bindings.key_mappings`` have changed:: + + @hook.config_changed('bindings') + def on_config_changed(): + ... + """ def __init__(self, option_filter: str = None) -> None: self._filter = option_filter diff --git a/qutebrowser/api/interceptor.py b/qutebrowser/api/interceptor.py index a40635fca..634ae1409 100644 --- a/qutebrowser/api/interceptor.py +++ b/qutebrowser/api/interceptor.py @@ -27,7 +27,13 @@ from qutebrowser.extensions.interceptors import Request def register(interceptor: interceptors.InterceptorType) -> None: """Register a request interceptor. - Whenever a request happens, the interceptor gets called with a Request - object. + Whenever a request happens, the interceptor gets called with a + :class:`Request` object. + + Example:: + + def intercept(request: interceptor.Request) -> None: + if request.request_url.host() == 'badhost.example.com': + request.block() """ interceptors.register(interceptor) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 3bd4c55c3..029394657 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -141,14 +141,11 @@ class TabData: class AbstractAction: - """Attribute of AbstractTab for Qt WebActions. - - Class attributes (overridden by subclasses): - action_class: The class actions are defined on (QWeb{Engine,}Page) - action_base: The type of the actions (QWeb{Engine,}Page.WebAction) - """ + """Attribute ``action`` of AbstractTab for Qt WebActions.""" + # The class actions are defined on (QWeb{Engine,}Page) action_class = None # type: type + # The type of the actions (QWeb{Engine,}Page.WebAction) action_base = None # type: type def __init__(self, tab: 'AbstractTab') -> None: @@ -200,7 +197,7 @@ class AbstractAction: class AbstractPrinting: - """Attribute of AbstractTab for printing the page.""" + """Attribute ``printing`` of AbstractTab for printing the page.""" def __init__(self, tab: 'AbstractTab') -> None: self._widget = None @@ -271,7 +268,7 @@ class AbstractPrinting: class AbstractSearch(QObject): - """Attribute of AbstractTab for doing searches. + """Attribute ``search`` of AbstractTab for doing searches. Attributes: text: The last thing this view was searched for. @@ -279,15 +276,14 @@ class AbstractSearch(QObject): this view. _flags: The flags of the last search (needs to be set by subclasses). _widget: The underlying WebView widget. - - Signals: - finished: Emitted when a search was finished. - arg: True if the text was found, False otherwise. - cleared: Emitted when an existing search was cleared. """ + #: Signal emitted when a search was finished + #: (True if the text was found, False otherwise) finished = pyqtSignal(bool) + #: Signal emitted when an existing search was cleared. cleared = pyqtSignal() + _Callback = typing.Callable[[bool], None] def __init__(self, tab: 'AbstractTab', parent: QWidget = None): @@ -350,17 +346,13 @@ class AbstractSearch(QObject): class AbstractZoom(QObject): - """Attribute of AbstractTab for controlling zoom. - - Attributes: - _neighborlist: A NeighborList with the zoom levels. - _default_zoom_changed: Whether the zoom was changed from the default. - """ + """Attribute ``zoom`` of AbstractTab for controlling zoom.""" def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None: super().__init__(parent) self._tab = tab self._widget = None + # Whether zoom was changed from the default. self._default_zoom_changed = False self._init_neighborlist() config.instance.changed.connect(self._on_config_changed) @@ -375,7 +367,9 @@ class AbstractZoom(QObject): self._init_neighborlist() def _init_neighborlist(self) -> None: - """Initialize self._neighborlist.""" + """Initialize self._neighborlist. + + It is a NeighborList with the zoom levels.""" levels = config.val.zoom.levels self._neighborlist = usertypes.NeighborList( levels, mode=usertypes.NeighborList.Modes.edge) @@ -427,15 +421,12 @@ class AbstractZoom(QObject): class AbstractCaret(QObject): - """Attribute of AbstractTab for caret browsing. - - Signals: - selection_toggled: Emitted when the selection was toggled. - arg: Whether the selection is now active. - follow_selected_done: Emitted when a follow_selection action is done. - """ + """Attribute ``caret`` of AbstractTab for caret browsing.""" + #: Signal emitted when the selection was toggled. + #: (argument - whether the selection is now active) selection_toggled = pyqtSignal(bool) + #: Emitted when a ``follow_selection`` action is done. follow_selected_done = pyqtSignal() def __init__(self, @@ -522,16 +513,12 @@ class AbstractCaret(QObject): class AbstractScroller(QObject): - """Attribute of AbstractTab to manage scroll position. - - Signals: - perc_changed: The scroll position changed. - before_jump_requested: - Emitted by other code when the user requested a jump. - Used to set the special ' mark so the user can return. - """ + """Attribute ``scroller`` of AbstractTab to manage scroll position.""" + #: Signal emitted when the scroll position changed (int, int) perc_changed = pyqtSignal(int, int) + #: Signal emitted before the user requested a jump. + #: Used to set the special ' mark so the user can return. before_jump_requested = pyqtSignal() def __init__(self, tab: 'AbstractTab', parent: QWidget = None): @@ -833,42 +820,46 @@ class AbstractTabPrivate: class AbstractTab(QWidget): - """An adapter for QWebView/QWebEngineView representing a single tab. - - Signals: - See related Qt signals. - - new_tab_requested: Emitted when a new tab should be opened with the - given URL. - load_status_changed: The loading status changed - fullscreen_requested: Fullscreen display was requested by the page. - arg: True if fullscreen should be turned on, - False if it should be turned off. - renderer_process_terminated: Emitted when the underlying renderer - process terminated. - arg 0: A TerminationStatus member. - arg 1: The exit code. - before_load_started: Emitted before we tell Qt to open a URL. - """ + """An adapter for QWebView/QWebEngineView representing a single tab.""" + #: Signal emitted when a website requests to close this tab. window_close_requested = pyqtSignal() + #: Signal emitted when a link is hovered (the hover text) link_hovered = pyqtSignal(str) + #: Signal emitted when a page started loading load_started = pyqtSignal() + #: Signal emitted when a page is loading (progress percentage) load_progress = pyqtSignal(int) + #: Signal emitted when a page finished loading (success as bool) load_finished = pyqtSignal(bool) + #: Signal emitted when a page's favicon changed (icon as QIcon) icon_changed = pyqtSignal(QIcon) + #: Signal emitted when a page's title changed (new title as str) title_changed = pyqtSignal(str) - load_status_changed = pyqtSignal(usertypes.LoadStatus) + #: Signal emitted when a new tab should be opened (url as QUrl) new_tab_requested = pyqtSignal(QUrl) + #: Signal emitted when a page's URL changed (url as QUrl) url_changed = pyqtSignal(QUrl) - shutting_down = pyqtSignal() + #: Signal emitted when a tab's content size changed + #: (new size as QSizeF) contents_size_changed = pyqtSignal(QSizeF) - # url, requested url, title - history_item_triggered = pyqtSignal(QUrl, QUrl, str) + #: Signal emitted when a page requested full-screen (bool) fullscreen_requested = pyqtSignal(bool) - renderer_process_terminated = pyqtSignal(TerminationStatus, int) + #: Signal emitted before load starts (URL as QUrl) before_load_started = pyqtSignal(QUrl) + # Signal emitted when a page's load status changed + # (argument: usertypes.LoadStatus) + load_status_changed = pyqtSignal(usertypes.LoadStatus) + # Signal emitted before shutting down + shutting_down = pyqtSignal() + # Signal emitted when a history item should be added + history_item_triggered = pyqtSignal(QUrl, QUrl, str) + # Signal emitted when the underlying renderer process terminated. + # arg 0: A TerminationStatus member. + # arg 1: The exit code. + renderer_process_terminated = pyqtSignal(TerminationStatus, int) + def __init__(self, *, win_id: int, private: bool, parent: QWidget = None) -> None: self.is_private = private diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py index a22facfbd..c00f247f6 100644 --- a/qutebrowser/browser/webelem.py +++ b/qutebrowser/browser/webelem.py @@ -141,20 +141,9 @@ class AbstractWebElement(collections.abc.MutableMapping): def rect_on_view(self, *, elem_geometry=None, no_js=False): """Get the geometry of the element relative to the webview. - Uses the getClientRects() JavaScript method to obtain the collection of - rectangles containing the element and returns the first rectangle which - is large enough (larger than 1px times 1px). If all rectangles returned - by getClientRects() are too small, falls back to elem.rect_on_view(). - - Skipping of small rectangles is due to elements containing other - elements with "display:block" style, see - https://github.com/qutebrowser/qutebrowser/issues/1298 - Args: elem_geometry: The geometry of the element, or None. - Calling QWebElement::geometry is rather expensive so - we want to avoid doing it twice. - no_js: Fall back to the Python implementation + no_js: Fall back to the Python implementation. """ raise NotImplementedError diff --git a/qutebrowser/extensions/interceptors.py b/qutebrowser/extensions/interceptors.py index 4a3ac17d4..269c82ab8 100644 --- a/qutebrowser/extensions/interceptors.py +++ b/qutebrowser/extensions/interceptors.py @@ -34,8 +34,12 @@ class Request: """A request which can be intercepted/blocked.""" + #: The URL of the page being shown. first_party_url = attr.ib() # type: QUrl + + #: The URL of the file being requested. request_url = attr.ib() # type: QUrl + is_blocked = attr.ib(False) # type: bool def block(self) -> None: diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py index b496273f8..6731721aa 100644 --- a/qutebrowser/utils/message.py +++ b/qutebrowser/utils/message.py @@ -42,12 +42,12 @@ def _log_stack(typ: str, stack: str) -> None: def error(message: str, *, stack: str = None, replace: bool = False) -> None: - """Convenience function to display an error message in the statusbar. + """Display an error message. Args: - message: The message to show - stack: The stack trace to show. - replace: Replace existing messages with replace=True + message: The message to show. + stack: The stack trace to show (if any). + replace: Replace existing messages which are still being shown. """ if stack is None: stack = ''.join(traceback.format_stack()) @@ -60,11 +60,11 @@ def error(message: str, *, stack: str = None, replace: bool = False) -> None: def warning(message: str, *, replace: bool = False) -> None: - """Convenience function to display a warning message in the statusbar. + """Display a warning message. Args: - message: The message to show - replace: Replace existing messages with replace=True + message: The message to show. + replace: Replace existing messages which are still being shown. """ _log_stack('warning', ''.join(traceback.format_stack())) log.message.warning(message) @@ -72,11 +72,11 @@ def warning(message: str, *, replace: bool = False) -> None: def info(message: str, *, replace: bool = False) -> None: - """Convenience function to display an info message in the statusbar. + """Display an info message. Args: - message: The message to show - replace: Replace existing messages with replace=True + message: The message to show. + replace: Replace existing messages which are still being shown. """ log.message.info(message) global_bridge.show(usertypes.MessageLevel.info, message, replace) diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index c948df48f..84b7e7f9b 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -210,15 +210,33 @@ PromptMode = enum.Enum('PromptMode', ['yesno', 'text', 'user_pwd', 'alert', 'download']) -# Where to open a clicked link. -ClickTarget = enum.Enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window', - 'hover']) +class ClickTarget(enum.Enum): + + """How to open a clicked link.""" + + normal = 0 #: Open the link in the current tab + tab = 1 #: Open the link in a new foreground tab + tab_bg = 2 #: Open the link in a new background tab + window = 3 #: Open the link in a new window + hover = 4 #: Only hover over the link -# Key input modes -KeyMode = enum.Enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt', - 'insert', 'passthrough', 'caret', 'set_mark', - 'jump_mark', 'record_macro', 'run_macro']) +class KeyMode(enum.Enum): + + """Key input modes.""" + + normal = 1 #: Normal mode (no mode was entered) + hint = 2 #: Hint mode (showing labels for links) + command = 3 #: Command mode (after pressing the colon key) + yesno = 4 #: Yes/No prompts + prompt = 5 #: Text prompts + insert = 6 #: Insert mode (passing through most keys) + passthrough = 7 #: Passthrough mode (passing through all keys) + caret = 8 #: Caret mode (moving cursor with keys) + set_mark = 9 + jump_mark = 10 + record_macro = 11 + run_macro = 12 class Exit(enum.IntEnum): @@ -241,8 +259,14 @@ LoadStatus = enum.Enum('LoadStatus', ['none', 'success', 'success_https', Backend = enum.Enum('Backend', ['QtWebKit', 'QtWebEngine']) -# JS world for QtWebEngine -JsWorld = enum.Enum('JsWorld', ['main', 'application', 'user', 'jseval']) +class JsWorld(enum.Enum): + + """World/context to run JavaScript code in.""" + + main = 1 #: Same world as the web page's JavaScript. + application = 2 #: Application world, used by qutebrowser internally. + user = 3 #: User world, currently not used. + jseval = 4 #: World used for the jseval-command. # Log level of a JS message. This needs to match up with the keys allowed for