Add a :scroll-to-anchor command

Fixes #2784
This commit is contained in:
Florian Bruhin 2018-03-19 19:18:33 +01:00
parent e50068021d
commit f5d7605ae0
8 changed files with 37 additions and 12 deletions

View File

@ -18,6 +18,11 @@ breaking changes (such as renamed commands) can happen in minor releases.
v1.3.0 (unreleased)
-------------------
Added
~~~~~
- New `:scroll-to-anchor` command to scroll to an anchor in the document.
Changed
~~~~~~~

View File

@ -93,6 +93,7 @@ It is possible to run or bind multiple commands by separating them with `;;`.
|<<scroll,scroll>>|Scroll the current tab in the given direction.
|<<scroll-page,scroll-page>>|Scroll the frame page-wise.
|<<scroll-px,scroll-px>>|Scroll the current tab by 'count * dx/dy' pixels.
|<<scroll-to-anchor,scroll-to-anchor>>|Scroll to the given anchor in the document.
|<<scroll-to-perc,scroll-to-perc>>|Scroll to a specific percentage of the page.
|<<search,search>>|Search for a text on the current page. With no text, clear results.
|<<search-next,search-next>>|Continue the search to the ([count]th) next term.
@ -1024,6 +1025,15 @@ Scroll the current tab by 'count * dx/dy' pixels.
==== count
multiplier
[[scroll-to-anchor]]
=== scroll-to-anchor
Syntax: +:scroll-to-anchor 'name'+
Scroll to the given anchor in the document.
==== positional arguments
* +'name'+: The anchor to scroll to.
[[scroll-to-perc]]
=== scroll-to-perc
Syntax: +:scroll-to-perc [*--horizontal*] ['perc']+

View File

@ -446,6 +446,9 @@ class AbstractScroller(QObject):
def to_point(self, point):
raise NotImplementedError
def to_anchor(self, name):
raise NotImplementedError
def delta(self, x=0, y=0):
raise NotImplementedError

View File

@ -768,6 +768,15 @@ class CommandDispatcher:
self._current_widget().scroller.to_perc(x, y)
@cmdutils.register(instance='command-dispatcher', scope='window')
def scroll_to_anchor(self, name):
"""Scroll to the given anchor in the document.
Args:
name: The anchor to scroll to.
"""
self._current_widget().scroller.to_anchor(name)
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('count', count=True)
@cmdutils.argument('top_navigate', metavar='ACTION',

View File

@ -427,6 +427,11 @@ class WebEngineScroller(browsertab.AbstractScroller):
js_code = javascript.assemble('window', 'scroll', point.x(), point.y())
self._tab.run_js_async(js_code)
def to_anchor(self, name):
url = self._tab.url()
url.setFragment(name)
self._tab.openurl(url)
def delta(self, x=0, y=0):
self._tab.run_js_async(javascript.assemble('window', 'scrollBy', x, y))

View File

@ -426,6 +426,9 @@ class WebKitScroller(browsertab.AbstractScroller):
def to_point(self, point):
self._widget.page().mainFrame().setScrollPosition(point)
def to_anchor(self, name):
self._widget.page().mainFrame().scrollToAnchor(name)
def delta(self, x=0, y=0):
qtutils.check_overflow(x, 'int')
qtutils.check_overflow(y, 'int')

View File

@ -108,16 +108,6 @@ class JSTester:
self.tab.run_js_async(source, callback_checker.callback, world=world)
callback_checker.check(expected)
def scroll_anchor(self, name):
"""Scroll the main frame to the given anchor."""
# FIXME This might be useful in the tab API?
assert self.tab.backend == usertypes.Backend.QtWebKit
page = self.tab._widget.page()
old_pos = page.mainFrame().scrollPosition()
page.mainFrame().scrollToAnchor(name)
new_pos = page.mainFrame().scrollPosition()
assert old_pos != new_pos
@pytest.fixture
def js_tester_webkit(webkit_tab, qtbot):

View File

@ -86,7 +86,7 @@ def test_simple(caret_tester):
def test_scrolled_down(caret_tester):
"""Test with multiple text blocks with the viewport scrolled down."""
caret_tester.js.load('position_caret/scrolled_down.html')
caret_tester.js.scroll_anchor('anchor')
caret_tester.js.tab.scroller.to_anchor('anchor')
caret_tester.check_scrolled()
caret_tester.check()
@ -103,6 +103,6 @@ def test_invisible(caret_tester, style):
def test_scrolled_down_img(caret_tester):
"""Test with an image at the top with the viewport scrolled down."""
caret_tester.js.load('position_caret/scrolled_down_img.html')
caret_tester.js.scroll_anchor('anchor')
caret_tester.js.tab.scroller.to_anchor('anchor')
caret_tester.check_scrolled()
caret_tester.check()