summaryrefslogtreecommitdiff
path: root/qutebrowser/browser/webengine/webenginetab.py
diff options
context:
space:
mode:
Diffstat (limited to 'qutebrowser/browser/webengine/webenginetab.py')
-rw-r--r--qutebrowser/browser/webengine/webenginetab.py135
1 files changed, 63 insertions, 72 deletions
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index 0a2333afc..1d02f7e99 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -104,83 +104,33 @@ class _WebEngineSearchWrapHandler:
Attributes:
flag_wrap: An additional flag indicating whether the last search
used wrapping.
- _active_match: The 1-based index of the currently active match
- on the page.
- _total_matches: The total number of search matches on the page.
- _nowrap_available: Whether the functionality to prevent wrapping
- is available.
+ nowrap_available: Whether the functionality to prevent wrapping
+ is available.
"""
def __init__(self):
- self._active_match = 0
- self._total_matches = 0
self.flag_wrap = True
- self._nowrap_available = False
+ self.nowrap_available = False
- def connect_signal(self, page):
- """Connect to the findTextFinished signal of the page.
-
- Args:
- page: The QtWebEnginePage to connect to this handler.
- """
- if not qtutils.version_check("5.14"):
- return
-
- try:
- # pylint: disable=unused-import
- from PyQt5.QtWebEngineCore import QWebEngineFindTextResult
- except ImportError:
- # WORKAROUND for some odd PyQt/packaging bug where the
- # findTextResult signal is available, but QWebEngineFindTextResult
- # is not. Seems to happen on e.g. Gentoo.
- log.webview.warning("Could not import QWebEngineFindTextResult "
- "despite running on Qt 5.14. You might need "
- "to rebuild PyQtWebEngine.")
- return
-
- page.findTextFinished.connect(self._store_match_data)
- self._nowrap_available = True
-
- def _store_match_data(self, result):
- """Store information on the last match.
-
- The information will be checked against when wrapping is turned off.
-
- Args:
- result: A FindTextResult passed by the findTextFinished signal.
- """
- self._active_match = result.activeMatch()
- self._total_matches = result.numberOfMatches()
- log.webview.debug("Active search match: {}/{}"
- .format(self._active_match, self._total_matches))
-
- def reset_match_data(self):
- """Reset match information.
-
- Stale information could lead to next_result or prev_result misbehaving.
- """
- self._active_match = 0
- self._total_matches = 0
-
- def prevent_wrapping(self, *, going_up):
+ def prevent_wrapping(self, current_match, total_match_count, *, going_up):
"""Prevent wrapping if possible and required.
Returns True if a wrap was prevented and False if not.
Args:
+ current_match: The currently active search match on the page.
+ total_match_count: The total number of search matches on the page.
going_up: Whether the search would scroll the page up or down.
"""
- if (not self._nowrap_available or
- self.flag_wrap or self._total_matches == 0):
- return False
- elif going_up and self._active_match == 1:
- message.info("Search hit TOP")
- return True
- elif not going_up and self._active_match == self._total_matches:
- message.info("Search hit BOTTOM")
- return True
- else:
- return False
+ return (
+ self.nowrap_available and
+ not self.flag_wrap and
+ total_match_count != 0 and
+ (
+ going_up and current_match == 1 or
+ not going_up and current_match == total_match_count
+ )
+ )
class WebEngineSearch(browsertab.AbstractSearch):
@@ -191,6 +141,7 @@ class WebEngineSearch(browsertab.AbstractSearch):
_flags: The QWebEnginePage.FindFlags of the last search.
_pending_searches: How many searches have been started but not called
back yet.
+
"""
_widget: webview.WebEngineView
@@ -199,7 +150,6 @@ class WebEngineSearch(browsertab.AbstractSearch):
super().__init__(tab, parent)
self._flags = self._empty_flags()
self._pending_searches = 0
- # The API necessary to stop wrapping was added in this version
self._wrap_handler = _WebEngineSearchWrapHandler()
def _empty_flags(self):
@@ -214,7 +164,25 @@ class WebEngineSearch(browsertab.AbstractSearch):
return flags
def connect_signals(self):
- self._wrap_handler.connect_signal(self._widget.page())
+ """Connect the signals necessary for this class to function."""
+ # The API necessary to stop wrapping was added in this version
+ if not qtutils.version_check("5.14"):
+ return
+
+ try:
+ # pylint: disable=unused-import
+ from PyQt5.QtWebEngineCore import QWebEngineFindTextResult
+ except ImportError:
+ # WORKAROUND for some odd PyQt/packaging bug where the
+ # findTextResult signal is available, but QWebEngineFindTextResult
+ # is not. Seems to happen on e.g. Gentoo.
+ log.webview.warning("Could not import QWebEngineFindTextResult "
+ "despite running on Qt 5.14. You might need "
+ "to rebuild PyQtWebEngine.")
+ return
+
+ self._wrap_handler.nowrap_available = True
+ self._widget.page().findTextFinished.connect(self._on_find_finished)
def _find(self, text, flags, callback, caller):
"""Call findText on the widget."""
@@ -254,6 +222,14 @@ class WebEngineSearch(browsertab.AbstractSearch):
self._widget.page().findText(text, flags, wrapped_callback)
+ def _on_find_finished(self, find_text_result):
+ """Unwrap the result, store it, and pass it along."""
+ self.current_match = find_text_result.activeMatch()
+ self.total_match_count = find_text_result.numberOfMatches()
+ log.webview.debug("Active search match: {}/{}"
+ .format(self.current_match, self.total_match_count))
+ self.search_match_changed.emit(self.current_match, self.total_match_count)
+
def search(self, text, *, ignore_case=usertypes.IgnoreCase.never,
reverse=False, wrap=True, result_cb=None):
# Don't go to next entry on duplicate search
@@ -265,7 +241,7 @@ class WebEngineSearch(browsertab.AbstractSearch):
self.text = text
self._flags = self._args_to_flags(reverse, ignore_case)
- self._wrap_handler.reset_match_data()
+ self._reset_match_data()
self._wrap_handler.flag_wrap = wrap
self._find(text, self._flags, result_cb, 'search')
@@ -273,29 +249,44 @@ class WebEngineSearch(browsertab.AbstractSearch):
def clear(self):
if self.search_displayed:
self.cleared.emit()
+ self.search_match_changed.emit(0, 0)
self.search_displayed = False
- self._wrap_handler.reset_match_data()
+ self._reset_match_data()
self._widget.page().findText('')
def prev_result(self, *, result_cb=None):
# The int() here makes sure we get a copy of the flags.
flags = QWebEnginePage.FindFlags(int(self._flags))
if flags & QWebEnginePage.FindBackward:
- if self._wrap_handler.prevent_wrapping(going_up=False):
+ if self._wrap_handler.prevent_wrapping(self.current_match,
+ self.total_match_count, going_up=False):
+ result_cb(True)
return
flags &= ~QWebEnginePage.FindBackward
else:
- if self._wrap_handler.prevent_wrapping(going_up=True):
+ if self._wrap_handler.prevent_wrapping(self.current_match,
+ self.total_match_count, going_up=True):
+ result_cb(True)
return
flags |= QWebEnginePage.FindBackward
self._find(self.text, flags, result_cb, 'prev_result')
def next_result(self, *, result_cb=None):
going_up = self._flags & QWebEnginePage.FindBackward
- if self._wrap_handler.prevent_wrapping(going_up=going_up):
+ if self._wrap_handler.prevent_wrapping(self.current_match,
+ self.total_match_count, going_up=going_up):
+ result_cb(True)
return
self._find(self.text, self._flags, result_cb, 'next_result')
+ def _reset_match_data(self):
+ """Reset match counter information.
+
+ Stale information could lead to next_result or prev_result misbehaving.
+ """
+ self.current_match = 0
+ self.total_match_count = 0
+
class WebEngineCaret(browsertab.AbstractCaret):