diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 6ced51110..7f6c6d4af 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -39,7 +39,8 @@ import pygments.formatters from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners from qutebrowser.config import config, configexc -from qutebrowser.browser import urlmarks, browsertab, inspector, navigate +from qutebrowser.browser import (urlmarks, browsertab, inspector, navigate, + webelem) from qutebrowser.browser.webkit import webkitelem, downloads, mhtml from qutebrowser.keyinput import modeman from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils, @@ -1559,7 +1560,11 @@ class CommandDispatcher: if elem is None: message.error(self._win_id, "No element found!") return - elem.click(target) + try: + elem.click(target) + except webelem.Error as e: + message.error(self._win_id, str(e)) + return # def multiple_cb(elems): # """Click multiple elements (with only one expected).""" diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 538f91928..5fad6cd2a 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -211,13 +211,16 @@ class HintActions: window=self._win_id) tabbed_browser.set_mark("'") - if context.target == Target.hover: - elem.hover() - elif context.target == Target.current: - elem.remove_blank_target() - elem.click(target_mapping[context.target]) - else: - elem.click(target_mapping[context.target]) + try: + if context.target == Target.hover: + elem.hover() + elif context.target == Target.current: + elem.remove_blank_target() + elem.click(target_mapping[context.target]) + else: + elem.click(target_mapping[context.target]) + except webelem.Error as e: + raise HintingError(str(e)) def yank(self, url, context): """Yank an element to the clipboard or primary selection. diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py index 0887bb745..008d6b280 100644 --- a/qutebrowser/browser/webelem.py +++ b/qutebrowser/browser/webelem.py @@ -353,7 +353,10 @@ class AbstractWebElement(collections.abc.MutableMapping): rect.setWidth(rect.height()) else: rect.setHeight(rect.width()) - return rect.center() + pos = rect.center() + if pos.x() < 0 or pos.y() < 0: + raise Error("Element position is out of view!") + return pos def click(self, click_target): """Simulate a click on the element.""" diff --git a/tests/end2end/data/scroll/simple.html b/tests/end2end/data/scroll/simple.html index e7172b374..2b1412ea4 100644 --- a/tests/end2end/data/scroll/simple.html +++ b/tests/end2end/data/scroll/simple.html @@ -5,6 +5,7 @@
0 1 diff --git a/tests/end2end/features/hints.feature b/tests/end2end/features/hints.feature index d590987f7..683defd8c 100644 --- a/tests/end2end/features/hints.feature +++ b/tests/end2end/features/hints.feature @@ -9,6 +9,14 @@ Feature: Using hints And I hint with args "links normal" and follow xyz Then the error "No hint xyz!" should be shown + Scenario: Following a link after scrolling down + When I open data/scroll/simple.html + And I run :hint links normal + And I wait for "hints: *" in the log + And I run :scroll-page 0 1 + And I run :follow-hint a + Then the error "Element position is out of view!" should be shown + ### Opening in current or new tab @qtwebengine_todo: createWindow is not implemented yet diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index cd60b15b4..493e6e8af 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -619,3 +619,9 @@ Feature: Various utility commands. And the following tabs should be open: - data/click_element.html - data/hello.txt (active) + + Scenario: Clicking an element which is out of view + When I open data/scroll/simple.html + And I run :scroll-page 0 1 + And I run :click-element id link + Then the error "Element position is out of view!" should be shown