From 540c62c232a8644da58bf1e44e3c5e2c9f1ec656 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 28 Jul 2016 10:34:51 +0200 Subject: [PATCH] Add only_visible to find_all_elements --- qutebrowser/browser/browsertab.py | 9 +++++++-- qutebrowser/browser/hints.py | 4 ++-- qutebrowser/browser/webkit/webelem.py | 5 ++--- qutebrowser/browser/webkit/webkittab.py | 6 +++++- tests/unit/browser/webkit/test_webelem.py | 4 ++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index cadc6a31d..996edc842 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -633,8 +633,13 @@ class AbstractTab(QWidget): def set_html(self, html, base_url): raise NotImplementedError - def find_all_elements(self, selector): - """Find all HTML elements matching a given selector.""" + def find_all_elements(self, selector, *, only_visible=False): + """Find all HTML elements matching a given selector. + + Args: + selector: The CSS selector to search for. + only_visible: Only show elements which are visible on screen. + """ raise NotImplementedError def __repr__(self): diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 4d4b590f6..d59267c92 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -656,8 +656,8 @@ class HintManager(QObject): def _init_elements(self): """Initialize the elements and labels based on the context set.""" selector = webelem.SELECTORS[self._context.group] - elems = self._context.tab.find_all_elements(selector) - elems = [e for e in elems if e.is_visible()] + elems = self._context.tab.find_all_elements(selector, + only_visible=True) filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True) elems = [e for e in elems if filterfunc(e)] if not elems: diff --git a/qutebrowser/browser/webkit/webelem.py b/qutebrowser/browser/webkit/webelem.py index 7b2236cc9..3325130a2 100644 --- a/qutebrowser/browser/webkit/webelem.py +++ b/qutebrowser/browser/webkit/webelem.py @@ -426,10 +426,9 @@ class WebElementWrapper(collections.abc.MutableMapping): rect.setHeight(rect.height() / zoom) return rect - def is_visible(self): - """Check if the given element is visible in the frame.""" + def is_visible(self, mainframe): + """Check if the given element is visible in the given frame.""" self._check_vanished() - mainframe = self._elem.webFrame() # CSS attributes which hide an element hidden_attributes = { 'visibility': 'hidden', diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index dca126f91..0db50212b 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -557,7 +557,7 @@ class WebKitTab(browsertab.AbstractTab): def set_html(self, html, base_url): self._widget.setHtml(html, base_url) - def find_all_elements(self, selector): + def find_all_elements(self, selector, *, only_visible=False): mainframe = self._widget.page().mainFrame() if mainframe is None: raise WebTabError("No frame focused!") @@ -567,6 +567,10 @@ class WebKitTab(browsertab.AbstractTab): for f in frames: for elem in f.findAllElements(selector): elems.append(webelem.WebElementWrapper(elem)) + + if only_visible: + elems = [e for e in elems if e.is_visible(mainframe)] + return elems @pyqtSlot() diff --git a/tests/unit/browser/webkit/test_webelem.py b/tests/unit/browser/webkit/test_webelem.py index b87a2f529..bfe1db224 100644 --- a/tests/unit/browser/webkit/test_webelem.py +++ b/tests/unit/browser/webkit/test_webelem.py @@ -672,9 +672,9 @@ class TestRectOnView: def test_passed_geometry(self, stubs, js_rect): """Make sure geometry isn't called when a geometry is passed.""" frame = stubs.FakeWebFrame(QRect(0, 0, 200, 200)) - raw_elem = get_webelem(frame=frame, js_rect_return=js_rect)._elem + elem = get_webelem(frame=frame, js_rect_return=js_rect) rect = QRect(10, 20, 30, 40) - assert webelem.rect_on_view(raw_elem, elem_geometry=rect) == rect + assert elem.rect_on_view(elem_geometry=rect) == rect assert not raw_elem.geometry.called @pytest.mark.parametrize('js_rect', [None, {}])