more extensive smart hinting
This commit is contained in:
parent
2f9051c6e1
commit
1dfcf99d22
@ -19,11 +19,13 @@
|
|||||||
|
|
||||||
"""A HintManager to draw hints over links."""
|
"""A HintManager to draw hints over links."""
|
||||||
|
|
||||||
import os
|
|
||||||
import string
|
|
||||||
import math
|
|
||||||
import functools
|
|
||||||
import collections
|
import collections
|
||||||
|
import itertools
|
||||||
|
import functools
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
|
||||||
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl,
|
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl,
|
||||||
QTimer)
|
QTimer)
|
||||||
@ -49,7 +51,6 @@ Target = usertypes.enum('Target', ['normal', 'tab', 'tab_fg', 'tab_bg',
|
|||||||
'fill', 'hover', 'download', 'userscript',
|
'fill', 'hover', 'download', 'userscript',
|
||||||
'spawn'])
|
'spawn'])
|
||||||
|
|
||||||
|
|
||||||
@pyqtSlot(usertypes.KeyMode)
|
@pyqtSlot(usertypes.KeyMode)
|
||||||
def on_mode_entered(mode, win_id):
|
def on_mode_entered(mode, win_id):
|
||||||
"""Stop hinting when insert mode was entered."""
|
"""Stop hinting when insert mode was entered."""
|
||||||
@ -139,6 +140,8 @@ class HintManager(QObject):
|
|||||||
Target.spawn: "Spawn command via hint",
|
Target.spawn: "Spawn command via hint",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FIRST_ALPHABETIC = re.compile('[A-Za-z]{3,}')
|
||||||
|
|
||||||
mouse_event = pyqtSignal('QMouseEvent')
|
mouse_event = pyqtSignal('QMouseEvent')
|
||||||
start_hinting = pyqtSignal(usertypes.ClickTarget)
|
start_hinting = pyqtSignal(usertypes.ClickTarget)
|
||||||
stop_hinting = pyqtSignal()
|
stop_hinting = pyqtSignal()
|
||||||
@ -247,27 +250,42 @@ class HintManager(QObject):
|
|||||||
A list of hint strings, in the same order as the elements.
|
A list of hint strings, in the same order as the elements.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def html_text_to_hint(text):
|
def html_elem_to_hints(elem):
|
||||||
if not text: return None
|
candidates = []
|
||||||
hint = text.split()[0].lower()
|
if elem.tagName() == "IMG":
|
||||||
if hint.isalpha():
|
"alt" in elem and candidates.append(elem["alt"])
|
||||||
return hint
|
"title" in elem and candidates.append(elem["title"])
|
||||||
return None
|
"src" in elem and candidates.append(elem["src"].split('/')[-1])
|
||||||
|
elif elem.tagName() == "A":
|
||||||
|
candidates.append(str(elem))
|
||||||
|
"title" in elem and candidates.append(elem["title"])
|
||||||
|
"href" in elem and candidates.append(elem["href"].split('/')[-1])
|
||||||
|
elif elem.tagName() == "INPUT":
|
||||||
|
"name" in elem and candidates.append(elem["name"])
|
||||||
|
for candidate in candidates:
|
||||||
|
if not candidate: continue
|
||||||
|
match = self.FIRST_ALPHABETIC.search(candidate)
|
||||||
|
if not match: continue
|
||||||
|
yield candidate[match.start():match.end()].lower()
|
||||||
|
|
||||||
def is_prefix(hint, existing):
|
def is_prefix(hint, existing):
|
||||||
return set(hint[:i+1] for i in range(len(hint))) & set(existing)
|
return set(hint[:i+1] for i in range(len(hint))) & set(existing)
|
||||||
|
|
||||||
|
def first_good_hint(new, existing):
|
||||||
|
for hint in new:
|
||||||
|
# some none's
|
||||||
|
if not hint: continue
|
||||||
|
if len(hint) < 3: continue
|
||||||
|
# not a prefix of an existing hint
|
||||||
|
if set(hint[:i+1] for i in range(len(hint))) & set(existing): continue
|
||||||
|
return hint
|
||||||
|
|
||||||
hints = []
|
hints = []
|
||||||
hintss = set()
|
used_hints = set()
|
||||||
words = iter(self._words)
|
words = iter(self._initialize_word_hints())
|
||||||
for elem in elems:
|
for elem in elems:
|
||||||
hint = html_text_to_hint(str(elem))
|
hint = first_good_hint(html_elem_to_hints(elem), used_hints) or next(words)
|
||||||
if hint and len(hint) >= 3 and not is_prefix(hint, hintss):
|
used_hints.add(hint)
|
||||||
hint = next(hint[:i] for i in range(3, len(hint) + 1)
|
|
||||||
if not is_prefix(hint[:i], hintss))
|
|
||||||
while not hint or is_prefix(hint, hintss):
|
|
||||||
hint = next(words)
|
|
||||||
hintss.add(hint)
|
|
||||||
hints.append(hint)
|
hints.append(hint)
|
||||||
return hints
|
return hints
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user