Split up HintActions from HintManager
This commit is contained in:
parent
d8521f43ee
commit
e2ae133757
@ -47,9 +47,9 @@ Target = usertypes.enum('Target', ['normal', 'current', 'tab', 'tab_fg',
|
|||||||
'userscript', 'spawn'])
|
'userscript', 'spawn'])
|
||||||
|
|
||||||
|
|
||||||
class WordHintingError(Exception):
|
class HintingError(Exception):
|
||||||
|
|
||||||
"""Exception raised on errors during word hinting."""
|
"""Exception raised on errors during hinting."""
|
||||||
|
|
||||||
|
|
||||||
def on_mode_entered(mode, win_id):
|
def on_mode_entered(mode, win_id):
|
||||||
@ -58,6 +58,32 @@ def on_mode_entered(mode, win_id):
|
|||||||
modeman.maybe_leave(win_id, usertypes.KeyMode.hint, 'insert mode')
|
modeman.maybe_leave(win_id, usertypes.KeyMode.hint, 'insert mode')
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_url(elem, baseurl):
|
||||||
|
"""Resolve a URL and check if we want to keep it.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem: The QWebElement to get the URL of.
|
||||||
|
baseurl: The baseurl of the current tab.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
A QUrl with the absolute URL, or None.
|
||||||
|
"""
|
||||||
|
for attr in ['href', 'src']:
|
||||||
|
if attr in elem:
|
||||||
|
text = elem[attr].strip()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
url = QUrl(text)
|
||||||
|
if not url.isValid():
|
||||||
|
return None
|
||||||
|
if url.isRelative():
|
||||||
|
url = baseurl.resolved(url)
|
||||||
|
qtutils.ensure_valid(url)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
class HintContext:
|
class HintContext:
|
||||||
|
|
||||||
"""Context namespace used for hinting.
|
"""Context namespace used for hinting.
|
||||||
@ -105,6 +131,199 @@ class HintContext:
|
|||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
class HintActions(QObject):
|
||||||
|
|
||||||
|
"""Actions which can be done after selecting a hint.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
mouse_event: Mouse event to be posted in the web view.
|
||||||
|
arg: A QMouseEvent
|
||||||
|
start_hinting: Emitted when hinting starts, before a link is clicked.
|
||||||
|
arg: The ClickTarget to use.
|
||||||
|
stop_hinting: Emitted after a link was clicked.
|
||||||
|
"""
|
||||||
|
|
||||||
|
mouse_event = pyqtSignal('QMouseEvent')
|
||||||
|
start_hinting = pyqtSignal(usertypes.ClickTarget)
|
||||||
|
stop_hinting = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, win_id, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self._win_id = win_id
|
||||||
|
|
||||||
|
def click(self, elem, context):
|
||||||
|
"""Click an element.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem: The QWebElement to click.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
target_mapping = {
|
||||||
|
Target.normal: usertypes.ClickTarget.normal,
|
||||||
|
Target.current: usertypes.ClickTarget.normal,
|
||||||
|
Target.tab_fg: usertypes.ClickTarget.tab,
|
||||||
|
Target.tab_bg: usertypes.ClickTarget.tab_bg,
|
||||||
|
Target.window: usertypes.ClickTarget.window,
|
||||||
|
Target.hover: usertypes.ClickTarget.normal,
|
||||||
|
}
|
||||||
|
if config.get('tabs', 'background-tabs'):
|
||||||
|
target_mapping[Target.tab] = usertypes.ClickTarget.tab_bg
|
||||||
|
else:
|
||||||
|
target_mapping[Target.tab] = usertypes.ClickTarget.tab
|
||||||
|
|
||||||
|
# Click the center of the largest square fitting into the top/left
|
||||||
|
# corner of the rectangle, this will help if part of the <a> element
|
||||||
|
# is hidden behind other elements
|
||||||
|
# https://github.com/The-Compiler/qutebrowser/issues/1005
|
||||||
|
rect = elem.rect_on_view()
|
||||||
|
if rect.width() > rect.height():
|
||||||
|
rect.setWidth(rect.height())
|
||||||
|
else:
|
||||||
|
rect.setHeight(rect.width())
|
||||||
|
pos = rect.center()
|
||||||
|
|
||||||
|
action = "Hovering" if context.target == Target.hover else "Clicking"
|
||||||
|
log.hints.debug("{} on '{}' at position {}".format(
|
||||||
|
action, elem.debug_text(), pos))
|
||||||
|
|
||||||
|
self.start_hinting.emit(target_mapping[context.target])
|
||||||
|
if context.target in [Target.tab, Target.tab_fg, Target.tab_bg,
|
||||||
|
Target.window]:
|
||||||
|
modifiers = Qt.ControlModifier
|
||||||
|
else:
|
||||||
|
modifiers = Qt.NoModifier
|
||||||
|
events = [
|
||||||
|
QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton,
|
||||||
|
Qt.NoModifier),
|
||||||
|
]
|
||||||
|
if context.target != Target.hover:
|
||||||
|
events += [
|
||||||
|
QMouseEvent(QEvent.MouseButtonPress, pos, Qt.LeftButton,
|
||||||
|
Qt.LeftButton, modifiers),
|
||||||
|
QMouseEvent(QEvent.MouseButtonRelease, pos, Qt.LeftButton,
|
||||||
|
Qt.NoButton, modifiers),
|
||||||
|
]
|
||||||
|
|
||||||
|
if context.target in [Target.normal, Target.current]:
|
||||||
|
# Set the pre-jump mark ', so we can jump back here after following
|
||||||
|
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||||
|
window=self._win_id)
|
||||||
|
tabbed_browser.set_mark("'")
|
||||||
|
|
||||||
|
if context.target == Target.current:
|
||||||
|
elem.remove_blank_target()
|
||||||
|
for evt in events:
|
||||||
|
self.mouse_event.emit(evt)
|
||||||
|
if elem.is_text_input() and elem.is_editable():
|
||||||
|
QTimer.singleShot(0, functools.partial(
|
||||||
|
elem.frame().page().triggerAction,
|
||||||
|
QWebPage.MoveToEndOfDocument))
|
||||||
|
QTimer.singleShot(0, self.stop_hinting.emit)
|
||||||
|
|
||||||
|
def yank(self, url, context):
|
||||||
|
"""Yank an element to the clipboard or primary selection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to open as a QUrl.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
sel = (context.target == Target.yank_primary and
|
||||||
|
utils.supports_selection())
|
||||||
|
|
||||||
|
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||||
|
utils.set_clipboard(urlstr, selection=sel)
|
||||||
|
|
||||||
|
msg = "Yanked URL to {}: {}".format(
|
||||||
|
"primary selection" if sel else "clipboard",
|
||||||
|
urlstr)
|
||||||
|
message.info(self._win_id, msg)
|
||||||
|
|
||||||
|
def run_cmd(self, url, context):
|
||||||
|
"""Run the command based on a hint URL.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to open as a QUrl.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
urlstr = url.toString(QUrl.FullyEncoded)
|
||||||
|
args = context.get_args(urlstr)
|
||||||
|
commandrunner = runners.CommandRunner(self._win_id)
|
||||||
|
commandrunner.run_safely(' '.join(args))
|
||||||
|
|
||||||
|
def preset_cmd_text(self, url, context):
|
||||||
|
"""Preset a commandline text based on a hint URL.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to open as a QUrl.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
urlstr = url.toDisplayString(QUrl.FullyEncoded)
|
||||||
|
args = context.get_args(urlstr)
|
||||||
|
text = ' '.join(args)
|
||||||
|
if text[0] not in modeparsers.STARTCHARS:
|
||||||
|
message.error(self._win_id,
|
||||||
|
"Invalid command text '{}'.".format(text),
|
||||||
|
immediately=True)
|
||||||
|
else:
|
||||||
|
message.set_cmd_text(self._win_id, text)
|
||||||
|
|
||||||
|
def download(self, elem, context):
|
||||||
|
"""Download a hint URL.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem: The QWebElement to download.
|
||||||
|
_context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
url = _resolve_url(elem, context.baseurl)
|
||||||
|
if url is None:
|
||||||
|
raise HintingError
|
||||||
|
if context.rapid:
|
||||||
|
prompt = False
|
||||||
|
else:
|
||||||
|
prompt = None
|
||||||
|
|
||||||
|
download_manager = objreg.get('download-manager', scope='window',
|
||||||
|
window=self._win_id)
|
||||||
|
download_manager.get(url, page=elem.frame().page(),
|
||||||
|
prompt_download_directory=prompt)
|
||||||
|
|
||||||
|
def call_userscript(self, elem, context):
|
||||||
|
"""Call a userscript from a hint.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem: The QWebElement to use in the userscript.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
cmd = context.args[0]
|
||||||
|
args = context.args[1:]
|
||||||
|
env = {
|
||||||
|
'QUTE_MODE': 'hints',
|
||||||
|
'QUTE_SELECTED_TEXT': str(elem),
|
||||||
|
'QUTE_SELECTED_HTML': elem.outer_xml(),
|
||||||
|
}
|
||||||
|
url = _resolve_url(elem, context.baseurl)
|
||||||
|
if url is not None:
|
||||||
|
env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
|
||||||
|
|
||||||
|
try:
|
||||||
|
userscripts.run_async(context.tab, cmd, *args, win_id=self._win_id,
|
||||||
|
env=env)
|
||||||
|
except userscripts.UnsupportedError as e:
|
||||||
|
message.error(self._win_id, str(e), immediately=True)
|
||||||
|
|
||||||
|
def spawn(self, url, context):
|
||||||
|
"""Spawn a simple command from a hint.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to open as a QUrl.
|
||||||
|
context: The HintContext to use.
|
||||||
|
"""
|
||||||
|
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||||
|
args = context.get_args(urlstr)
|
||||||
|
commandrunner = runners.CommandRunner(self._win_id)
|
||||||
|
commandrunner.run_safely('spawn ' + ' '.join(args))
|
||||||
|
|
||||||
|
|
||||||
class HintManager(QObject):
|
class HintManager(QObject):
|
||||||
|
|
||||||
"""Manage drawing hints over links or other elements.
|
"""Manage drawing hints over links or other elements.
|
||||||
@ -119,11 +338,7 @@ class HintManager(QObject):
|
|||||||
_filterstr: Used to save the filter string for restoring in rapid mode.
|
_filterstr: Used to save the filter string for restoring in rapid mode.
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
mouse_event: Mouse event to be posted in the web view.
|
See HintActions
|
||||||
arg: A QMouseEvent
|
|
||||||
start_hinting: Emitted when hinting starts, before a link is clicked.
|
|
||||||
arg: The ClickTarget to use.
|
|
||||||
stop_hinting: Emitted after a link was clicked.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
HINT_TEXTS = {
|
HINT_TEXTS = {
|
||||||
@ -155,6 +370,12 @@ class HintManager(QObject):
|
|||||||
self._context = None
|
self._context = None
|
||||||
self._filterstr = None
|
self._filterstr = None
|
||||||
self._word_hinter = WordHinter()
|
self._word_hinter = WordHinter()
|
||||||
|
|
||||||
|
self._actions = HintActions(win_id)
|
||||||
|
self._actions.start_hinting.connect(self.start_hinting)
|
||||||
|
self._actions.stop_hinting.connect(self.stop_hinting)
|
||||||
|
self._actions.mouse_event.connect(self.mouse_event)
|
||||||
|
|
||||||
mode_manager = objreg.get('mode-manager', scope='window',
|
mode_manager = objreg.get('mode-manager', scope='window',
|
||||||
window=win_id)
|
window=win_id)
|
||||||
mode_manager.left.connect(self.on_mode_left)
|
mode_manager.left.connect(self.on_mode_left)
|
||||||
@ -203,7 +424,7 @@ class HintManager(QObject):
|
|||||||
if hint_mode == 'word':
|
if hint_mode == 'word':
|
||||||
try:
|
try:
|
||||||
return self._word_hinter.hint(elems)
|
return self._word_hinter.hint(elems)
|
||||||
except WordHintingError as e:
|
except HintingError as e:
|
||||||
message.error(self._win_id, str(e), immediately=True)
|
message.error(self._win_id, str(e), immediately=True)
|
||||||
# falls back on letter hints
|
# falls back on letter hints
|
||||||
if hint_mode == 'number':
|
if hint_mode == 'number':
|
||||||
@ -405,204 +626,6 @@ class HintManager(QObject):
|
|||||||
message.error(self._win_id, "No suitable link found for this element.",
|
message.error(self._win_id, "No suitable link found for this element.",
|
||||||
immediately=True)
|
immediately=True)
|
||||||
|
|
||||||
def _click(self, elem, context):
|
|
||||||
"""Click an element.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
elem: The QWebElement to click.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
target_mapping = {
|
|
||||||
Target.normal: usertypes.ClickTarget.normal,
|
|
||||||
Target.current: usertypes.ClickTarget.normal,
|
|
||||||
Target.tab_fg: usertypes.ClickTarget.tab,
|
|
||||||
Target.tab_bg: usertypes.ClickTarget.tab_bg,
|
|
||||||
Target.window: usertypes.ClickTarget.window,
|
|
||||||
Target.hover: usertypes.ClickTarget.normal,
|
|
||||||
}
|
|
||||||
if config.get('tabs', 'background-tabs'):
|
|
||||||
target_mapping[Target.tab] = usertypes.ClickTarget.tab_bg
|
|
||||||
else:
|
|
||||||
target_mapping[Target.tab] = usertypes.ClickTarget.tab
|
|
||||||
|
|
||||||
# Click the center of the largest square fitting into the top/left
|
|
||||||
# corner of the rectangle, this will help if part of the <a> element
|
|
||||||
# is hidden behind other elements
|
|
||||||
# https://github.com/The-Compiler/qutebrowser/issues/1005
|
|
||||||
rect = elem.rect_on_view()
|
|
||||||
if rect.width() > rect.height():
|
|
||||||
rect.setWidth(rect.height())
|
|
||||||
else:
|
|
||||||
rect.setHeight(rect.width())
|
|
||||||
pos = rect.center()
|
|
||||||
|
|
||||||
action = "Hovering" if context.target == Target.hover else "Clicking"
|
|
||||||
log.hints.debug("{} on '{}' at position {}".format(
|
|
||||||
action, elem.debug_text(), pos))
|
|
||||||
|
|
||||||
self.start_hinting.emit(target_mapping[context.target])
|
|
||||||
if context.target in [Target.tab, Target.tab_fg, Target.tab_bg,
|
|
||||||
Target.window]:
|
|
||||||
modifiers = Qt.ControlModifier
|
|
||||||
else:
|
|
||||||
modifiers = Qt.NoModifier
|
|
||||||
events = [
|
|
||||||
QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton,
|
|
||||||
Qt.NoModifier),
|
|
||||||
]
|
|
||||||
if context.target != Target.hover:
|
|
||||||
events += [
|
|
||||||
QMouseEvent(QEvent.MouseButtonPress, pos, Qt.LeftButton,
|
|
||||||
Qt.LeftButton, modifiers),
|
|
||||||
QMouseEvent(QEvent.MouseButtonRelease, pos, Qt.LeftButton,
|
|
||||||
Qt.NoButton, modifiers),
|
|
||||||
]
|
|
||||||
|
|
||||||
if context.target in [Target.normal, Target.current]:
|
|
||||||
# Set the pre-jump mark ', so we can jump back here after following
|
|
||||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
|
||||||
window=self._win_id)
|
|
||||||
tabbed_browser.set_mark("'")
|
|
||||||
|
|
||||||
if context.target == Target.current:
|
|
||||||
elem.remove_blank_target()
|
|
||||||
for evt in events:
|
|
||||||
self.mouse_event.emit(evt)
|
|
||||||
if elem.is_text_input() and elem.is_editable():
|
|
||||||
QTimer.singleShot(0, functools.partial(
|
|
||||||
elem.frame().page().triggerAction,
|
|
||||||
QWebPage.MoveToEndOfDocument))
|
|
||||||
QTimer.singleShot(0, self.stop_hinting.emit)
|
|
||||||
|
|
||||||
def _yank(self, url, context):
|
|
||||||
"""Yank an element to the clipboard or primary selection.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The URL to open as a QUrl.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
sel = (context.target == Target.yank_primary and
|
|
||||||
utils.supports_selection())
|
|
||||||
|
|
||||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
|
||||||
utils.set_clipboard(urlstr, selection=sel)
|
|
||||||
|
|
||||||
msg = "Yanked URL to {}: {}".format(
|
|
||||||
"primary selection" if sel else "clipboard",
|
|
||||||
urlstr)
|
|
||||||
message.info(self._win_id, msg)
|
|
||||||
|
|
||||||
def _run_cmd(self, url, context):
|
|
||||||
"""Run the command based on a hint URL.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The URL to open as a QUrl.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
urlstr = url.toString(QUrl.FullyEncoded)
|
|
||||||
args = context.get_args(urlstr)
|
|
||||||
commandrunner = runners.CommandRunner(self._win_id)
|
|
||||||
commandrunner.run_safely(' '.join(args))
|
|
||||||
|
|
||||||
def _preset_cmd_text(self, url, context):
|
|
||||||
"""Preset a commandline text based on a hint URL.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The URL to open as a QUrl.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
urlstr = url.toDisplayString(QUrl.FullyEncoded)
|
|
||||||
args = context.get_args(urlstr)
|
|
||||||
text = ' '.join(args)
|
|
||||||
if text[0] not in modeparsers.STARTCHARS:
|
|
||||||
message.error(self._win_id,
|
|
||||||
"Invalid command text '{}'.".format(text),
|
|
||||||
immediately=True)
|
|
||||||
else:
|
|
||||||
message.set_cmd_text(self._win_id, text)
|
|
||||||
|
|
||||||
def _download(self, elem, context):
|
|
||||||
"""Download a hint URL.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
elem: The QWebElement to download.
|
|
||||||
_context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
url = self._resolve_url(elem, context.baseurl)
|
|
||||||
if url is None:
|
|
||||||
self._show_url_error()
|
|
||||||
return
|
|
||||||
if context.rapid:
|
|
||||||
prompt = False
|
|
||||||
else:
|
|
||||||
prompt = None
|
|
||||||
|
|
||||||
download_manager = objreg.get('download-manager', scope='window',
|
|
||||||
window=self._win_id)
|
|
||||||
download_manager.get(url, page=elem.frame().page(),
|
|
||||||
prompt_download_directory=prompt)
|
|
||||||
|
|
||||||
def _call_userscript(self, elem, context):
|
|
||||||
"""Call a userscript from a hint.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
elem: The QWebElement to use in the userscript.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
cmd = context.args[0]
|
|
||||||
args = context.args[1:]
|
|
||||||
env = {
|
|
||||||
'QUTE_MODE': 'hints',
|
|
||||||
'QUTE_SELECTED_TEXT': str(elem),
|
|
||||||
'QUTE_SELECTED_HTML': elem.outer_xml(),
|
|
||||||
}
|
|
||||||
url = self._resolve_url(elem, context.baseurl)
|
|
||||||
if url is not None:
|
|
||||||
env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
|
|
||||||
|
|
||||||
try:
|
|
||||||
userscripts.run_async(context.tab, cmd, *args, win_id=self._win_id,
|
|
||||||
env=env)
|
|
||||||
except userscripts.UnsupportedError as e:
|
|
||||||
message.error(self._win_id, str(e), immediately=True)
|
|
||||||
|
|
||||||
def _spawn(self, url, context):
|
|
||||||
"""Spawn a simple command from a hint.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The URL to open as a QUrl.
|
|
||||||
context: The HintContext to use.
|
|
||||||
"""
|
|
||||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
|
||||||
args = context.get_args(urlstr)
|
|
||||||
commandrunner = runners.CommandRunner(self._win_id)
|
|
||||||
commandrunner.run_safely('spawn ' + ' '.join(args))
|
|
||||||
|
|
||||||
def _resolve_url(self, elem, baseurl):
|
|
||||||
"""Resolve a URL and check if we want to keep it.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
elem: The QWebElement to get the URL of.
|
|
||||||
baseurl: The baseurl of the current tab.
|
|
||||||
|
|
||||||
Return:
|
|
||||||
A QUrl with the absolute URL, or None.
|
|
||||||
"""
|
|
||||||
for attr in ['href', 'src']:
|
|
||||||
if attr in elem:
|
|
||||||
text = elem[attr].strip()
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
url = QUrl(text)
|
|
||||||
if not url.isValid():
|
|
||||||
return None
|
|
||||||
if url.isRelative():
|
|
||||||
url = baseurl.resolved(url)
|
|
||||||
qtutils.ensure_valid(url)
|
|
||||||
return url
|
|
||||||
|
|
||||||
def _check_args(self, target, *args):
|
def _check_args(self, target, *args):
|
||||||
"""Check the arguments passed to start() and raise if they're wrong.
|
"""Check the arguments passed to start() and raise if they're wrong.
|
||||||
|
|
||||||
@ -684,7 +707,7 @@ class HintManager(QObject):
|
|||||||
if elem is None:
|
if elem is None:
|
||||||
message.error(self._win_id, "No {} links found!".format(word))
|
message.error(self._win_id, "No {} links found!".format(word))
|
||||||
return
|
return
|
||||||
url = self._resolve_url(elem, baseurl)
|
url = _resolve_url(elem, baseurl)
|
||||||
if url is None:
|
if url is None:
|
||||||
message.error(self._win_id, "No {} links found!".format(word))
|
message.error(self._win_id, "No {} links found!".format(word))
|
||||||
return
|
return
|
||||||
@ -955,38 +978,41 @@ class HintManager(QObject):
|
|||||||
self.handle_partial_key(keystr)
|
self.handle_partial_key(keystr)
|
||||||
self._context.to_follow = keystr
|
self._context.to_follow = keystr
|
||||||
return
|
return
|
||||||
|
|
||||||
# Handlers which take a QWebElement
|
# Handlers which take a QWebElement
|
||||||
elem_handlers = {
|
elem_handlers = {
|
||||||
Target.normal: self._click,
|
Target.normal: self._actions.click,
|
||||||
Target.current: self._click,
|
Target.current: self._actions.click,
|
||||||
Target.tab: self._click,
|
Target.tab: self._actions.click,
|
||||||
Target.tab_fg: self._click,
|
Target.tab_fg: self._actions.click,
|
||||||
Target.tab_bg: self._click,
|
Target.tab_bg: self._actions.click,
|
||||||
Target.window: self._click,
|
Target.window: self._actions.click,
|
||||||
Target.hover: self._click,
|
Target.hover: self._actions.click,
|
||||||
# _download needs a QWebElement to get the frame.
|
# _download needs a QWebElement to get the frame.
|
||||||
Target.download: self._download,
|
Target.download: self._actions.download,
|
||||||
Target.userscript: self._call_userscript,
|
Target.userscript: self._actions.call_userscript,
|
||||||
}
|
}
|
||||||
# Handlers which take a QUrl
|
# Handlers which take a QUrl
|
||||||
url_handlers = {
|
url_handlers = {
|
||||||
Target.yank: self._yank,
|
Target.yank: self._actions.yank,
|
||||||
Target.yank_primary: self._yank,
|
Target.yank_primary: self._actions.yank,
|
||||||
Target.run: self._run_cmd,
|
Target.run: self._actions.run_cmd,
|
||||||
Target.fill: self._preset_cmd_text,
|
Target.fill: self._actions.preset_cmd_text,
|
||||||
Target.spawn: self._spawn,
|
Target.spawn: self._actions.spawn,
|
||||||
}
|
}
|
||||||
elem = self._context.elems[keystr].elem
|
elem = self._context.elems[keystr].elem
|
||||||
|
|
||||||
if elem.frame() is None:
|
if elem.frame() is None:
|
||||||
message.error(self._win_id,
|
message.error(self._win_id,
|
||||||
"This element has no webframe.",
|
"This element has no webframe.",
|
||||||
immediately=True)
|
immediately=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._context.target in elem_handlers:
|
if self._context.target in elem_handlers:
|
||||||
handler = functools.partial(elem_handlers[self._context.target],
|
handler = functools.partial(elem_handlers[self._context.target],
|
||||||
elem, self._context)
|
elem, self._context)
|
||||||
elif self._context.target in url_handlers:
|
elif self._context.target in url_handlers:
|
||||||
url = self._resolve_url(elem, self._context.baseurl)
|
url = _resolve_url(elem, self._context.baseurl)
|
||||||
if url is None:
|
if url is None:
|
||||||
self._show_url_error()
|
self._show_url_error()
|
||||||
return
|
return
|
||||||
@ -994,6 +1020,7 @@ class HintManager(QObject):
|
|||||||
url, self._context)
|
url, self._context)
|
||||||
else:
|
else:
|
||||||
raise ValueError("No suitable handler found!")
|
raise ValueError("No suitable handler found!")
|
||||||
|
|
||||||
if not self._context.rapid:
|
if not self._context.rapid:
|
||||||
modeman.maybe_leave(self._win_id, usertypes.KeyMode.hint,
|
modeman.maybe_leave(self._win_id, usertypes.KeyMode.hint,
|
||||||
'followed')
|
'followed')
|
||||||
@ -1003,7 +1030,11 @@ class HintManager(QObject):
|
|||||||
# Undo keystring highlighting
|
# Undo keystring highlighting
|
||||||
for string, elem in self._context.elems.items():
|
for string, elem in self._context.elems.items():
|
||||||
elem.label.set_inner_xml(string)
|
elem.label.set_inner_xml(string)
|
||||||
handler()
|
|
||||||
|
try:
|
||||||
|
handler()
|
||||||
|
except HintingError:
|
||||||
|
self._show_url_error()
|
||||||
|
|
||||||
@cmdutils.register(instance='hintmanager', scope='tab', hide=True,
|
@cmdutils.register(instance='hintmanager', scope='tab', hide=True,
|
||||||
modes=[usertypes.KeyMode.hint])
|
modes=[usertypes.KeyMode.hint])
|
||||||
@ -1086,7 +1117,7 @@ class WordHinter:
|
|||||||
self.words.update(hints)
|
self.words.update(hints)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
error = "Word hints requires reading the file at {}: {}"
|
error = "Word hints requires reading the file at {}: {}"
|
||||||
raise WordHintingError(error.format(dictionary, str(e)))
|
raise HintingError(error.format(dictionary, str(e)))
|
||||||
|
|
||||||
def extract_tag_words(self, elem):
|
def extract_tag_words(self, elem):
|
||||||
"""Extract tag words form the given element."""
|
"""Extract tag words form the given element."""
|
||||||
@ -1155,7 +1186,7 @@ class WordHinter:
|
|||||||
for elem in elems:
|
for elem in elems:
|
||||||
hint = self.new_hint_for(elem, used_hints, words)
|
hint = self.new_hint_for(elem, used_hints, words)
|
||||||
if not hint:
|
if not hint:
|
||||||
raise WordHintingError("Not enough words in the dictionary.")
|
raise HintingError("Not enough words in the dictionary.")
|
||||||
used_hints.add(hint)
|
used_hints.add(hint)
|
||||||
hints.append(hint)
|
hints.append(hint)
|
||||||
return hints
|
return hints
|
||||||
|
Loading…
Reference in New Issue
Block a user