Make hints work
This commit is contained in:
parent
12b36de5b5
commit
fd678ff864
@ -222,6 +222,26 @@ class CurCommandDispatcher(QObject):
|
||||
"""Fire a completed hint."""
|
||||
self._tabs.currentWidget().hintmanager.fire(keystr)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cur')
|
||||
def prev_page(self):
|
||||
"""Click on a "previous" link."""
|
||||
widget = self._tabs.currentWidget()
|
||||
frame = widget.page_.currentFrame()
|
||||
if frame is None:
|
||||
message.error("No frame focused!")
|
||||
return
|
||||
widget.hintmanager.click_prevnext(frame, prev=True)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cur')
|
||||
def next_page(self):
|
||||
"""Click on a "next" link."""
|
||||
widget = self._tabs.currentWidget()
|
||||
frame = widget.page_.currentFrame()
|
||||
if frame is None:
|
||||
message.error("No frame focused!")
|
||||
return
|
||||
widget.hintmanager.click_prevnext(frame, prev=False)
|
||||
|
||||
@pyqtSlot(str, int)
|
||||
def search(self, text, flags):
|
||||
"""Search for text in the current page.
|
||||
|
@ -207,19 +207,24 @@ class HintManager(QObject):
|
||||
css, string))
|
||||
return doc.lastChild()
|
||||
|
||||
def _click(self, elem):
|
||||
def _click(self, elem, target=None, frame=None):
|
||||
"""Click an element.
|
||||
|
||||
Args:
|
||||
elem: The QWebElement to click.
|
||||
target_override: Target which overrides self._target
|
||||
"""
|
||||
if self._target == 'rapid':
|
||||
if target is not None:
|
||||
pass
|
||||
elif self._target == 'rapid':
|
||||
target = 'bgtab'
|
||||
else:
|
||||
target = self._target
|
||||
if frame is None:
|
||||
frame = self._frame
|
||||
self.set_open_target.emit(target)
|
||||
point = elem.geometry().topLeft()
|
||||
scrollpos = self._frame.scrollPosition()
|
||||
scrollpos = frame.scrollPosition()
|
||||
logging.debug("Clicking on \"{}\" at {}/{} - {}/{}".format(
|
||||
elem.toPlainText(), point.x(), point.y(), scrollpos.x(),
|
||||
scrollpos.y()))
|
||||
@ -281,22 +286,23 @@ class HintManager(QObject):
|
||||
def click_prevnext(self, frame, prev=False):
|
||||
"""Click a "previous"/"next" element on the page."""
|
||||
# First check for <link rel="prev(ious)|next">
|
||||
self.target='normal'
|
||||
elems = frame.findAllElements(webelem.SELECTORS['prevnext_rel'])
|
||||
rel_values = ['prev', 'previous'] if prev else ['next']
|
||||
for e in elems:
|
||||
if e.attribute('rel') in rel_values:
|
||||
self.click(e)
|
||||
self._click(e, 'normal', frame)
|
||||
return
|
||||
# Then check for regular links
|
||||
elems = frame.findAllElements(webelem.SELECTORS['prevnext'])
|
||||
option = 'prev-regexes' if prev else 'next-regexes'
|
||||
for regex in config.get('hints', option):
|
||||
for e in elems:
|
||||
if regex.match(e.toPlainText()):
|
||||
self.click(e)
|
||||
return
|
||||
message.error("No prev/forward links found!")
|
||||
if elems:
|
||||
for regex in config.get('hints', option):
|
||||
for e in elems:
|
||||
if regex.match(e.toPlainText()):
|
||||
self._click(e, 'normal', frame)
|
||||
return
|
||||
message.error("No {} links found!".format("prev" if prev
|
||||
else "forward"))
|
||||
|
||||
|
||||
def start(self, frame, baseurl, mode='all', target='normal'):
|
||||
|
@ -17,7 +17,9 @@
|
||||
|
||||
"""Setting options used for qutebrowser."""
|
||||
|
||||
import re
|
||||
import shlex
|
||||
from sre_constants import error as RegexError
|
||||
|
||||
from PyQt5.QtGui import QColor
|
||||
|
||||
@ -511,6 +513,42 @@ class KeyBindingName(BaseType):
|
||||
pass
|
||||
|
||||
|
||||
class Regex(BaseType):
|
||||
|
||||
"""A regular expression."""
|
||||
|
||||
def __init__(self, flags=0):
|
||||
self.flags = flags
|
||||
|
||||
def validate(self, value):
|
||||
try:
|
||||
re.compile(value, self.flags)
|
||||
except RegexError as e:
|
||||
raise ValidationError(value, "must be a valid regex - " + str(e))
|
||||
|
||||
def transform(self, value):
|
||||
return re.compile(value, self.flags)
|
||||
|
||||
|
||||
class RegexList(List):
|
||||
|
||||
"""A list of regexes."""
|
||||
|
||||
def __init__(self, flags=0):
|
||||
self.flags=flags
|
||||
|
||||
def transform(self, value):
|
||||
vals = super().transform(value)
|
||||
return [re.compile(pattern, self.flags) for pattern in vals]
|
||||
|
||||
def validate(self, value):
|
||||
try:
|
||||
self.transform(value)
|
||||
except RegexError as e:
|
||||
raise ValidationError(value, "must be a list valid regexes - " +
|
||||
str(e))
|
||||
|
||||
|
||||
class AutoSearch(BaseType):
|
||||
|
||||
"""Whether to start a search when something else than an URL is entered."""
|
||||
|
@ -24,6 +24,7 @@ SECTION_DESC: A dictionary with descriptions for sections.
|
||||
DATA: The config defaults, an OrderedDict of sections.
|
||||
"""
|
||||
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
|
||||
from qutebrowser.config._value import SettingValue
|
||||
@ -397,6 +398,18 @@ DATA = OrderedDict([
|
||||
('auto-follow',
|
||||
SettingValue(types.Bool(), 'true'),
|
||||
"Whether to auto-follow a hint if there's only one left."),
|
||||
|
||||
('next-regexes',
|
||||
SettingValue(types.RegexList(flags=re.IGNORECASE),
|
||||
r'\bnext\b,\bmore\b,\bnewer\b,^>$$,^(>>|»|→|≫)$$,'
|
||||
r'^(>|»|→|≫),(>|»|→|≫)$$'),
|
||||
"A comma-separated list of regexes to use for 'next' links."),
|
||||
|
||||
('prev-regexes',
|
||||
SettingValue(types.RegexList(flags=re.IGNORECASE),
|
||||
r'\bprev(ious)\b,\bback\b,\bolder\b,^<$$,^(<<|«|←|≪)$$,'
|
||||
r'^(<|«|←|≪),(<|«|←|≪)$$'),
|
||||
"A comma-separated list of regexes to use for 'prev' links."),
|
||||
)),
|
||||
|
||||
('searchengines', sect.ValueList(
|
||||
@ -456,6 +469,8 @@ DATA = OrderedDict([
|
||||
('PP', 'tabpaste sel'),
|
||||
('-', 'zoomout'),
|
||||
('+', 'zoomin'),
|
||||
('[[', 'prev_page'),
|
||||
(']]', 'next_page'),
|
||||
('<Ctrl-V>', 'enter_mode passthrough'),
|
||||
('<Ctrl-Q>', 'quit'),
|
||||
('<Ctrl-Shift-T>', 'undo'),
|
||||
|
@ -36,8 +36,8 @@ SELECTORS = {
|
||||
'input[type=tel], input[type=number], '
|
||||
'input[type=password], input[type=search], textarea'),
|
||||
'url': '[src], [href]',
|
||||
'prevnext_rel': 'link [role=link]',
|
||||
'prevnext': 'a button [role=button]',
|
||||
'prevnext_rel': 'link, [role=link]',
|
||||
'prevnext': 'a, button, [role=button]',
|
||||
}
|
||||
|
||||
SELECTORS['editable_focused'] = ', '.join(
|
||||
|
Loading…
Reference in New Issue
Block a user