Merge branch 'sphinx'

This commit is contained in:
Florian Bruhin 2018-12-12 16:02:37 +01:00
commit 37fec05d3e
20 changed files with 570 additions and 110 deletions

1
.gitignore vendored
View File

@ -41,3 +41,4 @@ TODO
/scripts/testbrowser/cpp/webengine/.qmake.stash
/scripts/dev/pylint_checkers/qute_pylint.egg-info
/misc/file_version_info.txt
/doc/extapi/_build

View File

View File

48
doc/extapi/api.rst Normal file
View File

@ -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:

179
doc/extapi/conf.py Normal file
View File

@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'qutebrowser extensions'
copyright = '2018, Florian Bruhin'
author = 'Florian Bruhin'
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = ''
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
]
autodoc_member_order = 'bysource'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'qutebrowserextensionsdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'qutebrowserextensions.tex', 'qutebrowser extensions Documentation',
'Florian Bruhin', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'qutebrowserextensions', 'qutebrowser extensions Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'qutebrowserextensions', 'qutebrowser extensions Documentation',
author, 'qutebrowserextensions', 'One line description of project.',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------

22
doc/extapi/index.rst Normal file
View File

@ -0,0 +1,22 @@
.. qutebrowser extensions documentation master file, created by
sphinx-quickstart on Tue Dec 11 18:59:44 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to qutebrowser extensions's documentation!
==================================================
.. toctree::
:maxdepth: 2
:caption: Contents:
api
tab
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

44
doc/extapi/tab.rst Normal file
View File

@ -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:

View File

@ -0,0 +1,21 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
alabaster==0.7.12
Babel==2.6.0
certifi==2018.11.29
chardet==3.0.4
docutils==0.14
idna==2.8
imagesize==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
packaging==18.0
Pygments==2.3.0
pyparsing==2.3.0
pytz==2018.7
requests==2.21.0
six==1.12.0
snowballstemmer==1.2.1
Sphinx==1.8.2
sphinxcontrib-websupport==1.1.0
urllib3==1.24.1

View File

@ -0,0 +1 @@
sphinx

View File

@ -17,7 +17,38 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""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__

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 <a> 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

View File

@ -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:

View File

@ -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)

View File

@ -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

11
tox.ini
View File

@ -199,3 +199,14 @@ deps =
-r{toxinidir}/misc/requirements/requirements-mypy.txt
commands =
{envpython} -m mypy qutebrowser {posargs}
[testenv:sphinx]
basepython = {env:PYTHON:python3}
passenv =
usedevelop = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-pyqt.txt
-r{toxinidir}/misc/requirements/requirements-sphinx.txt
commands =
{envpython} -m sphinx -jauto -W --color {posargs} doc/extapi/ doc/extapi/_build/