Move most :navigate code to browser.navigate
This commit is contained in:
parent
68595e1736
commit
778ccad39f
@ -22,7 +22,6 @@
|
|||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import shlex
|
import shlex
|
||||||
import posixpath
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication, QTabBar
|
from PyQt5.QtWidgets import QApplication, QTabBar
|
||||||
@ -40,7 +39,7 @@ import pygments.formatters
|
|||||||
|
|
||||||
from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
|
from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
|
||||||
from qutebrowser.config import config, configexc
|
from qutebrowser.config import config, configexc
|
||||||
from qutebrowser.browser import urlmarks, browsertab, inspector
|
from qutebrowser.browser import urlmarks, browsertab, inspector, navigate
|
||||||
from qutebrowser.browser.webkit import webelem, downloads, mhtml
|
from qutebrowser.browser.webkit import webelem, downloads, mhtml
|
||||||
from qutebrowser.keyinput import modeman
|
from qutebrowser.keyinput import modeman
|
||||||
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
|
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
|
||||||
@ -440,40 +439,6 @@ class CommandDispatcher:
|
|||||||
"""
|
"""
|
||||||
self._back_forward(tab, bg, window, count, forward=True)
|
self._back_forward(tab, bg, window, count, forward=True)
|
||||||
|
|
||||||
def _navigate_incdec(self, url, incdec, tab, background, window):
|
|
||||||
"""Helper method for :navigate when `where' is increment/decrement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The current url.
|
|
||||||
incdec: Either 'increment' or 'decrement'.
|
|
||||||
tab: Whether to open the link in a new tab.
|
|
||||||
background: Open the link in a new background tab.
|
|
||||||
window: Open the link in a new window.
|
|
||||||
"""
|
|
||||||
segments = set(config.get('general', 'url-incdec-segments'))
|
|
||||||
try:
|
|
||||||
new_url = urlutils.incdec_number(url, incdec, segments=segments)
|
|
||||||
except urlutils.IncDecError as error:
|
|
||||||
raise cmdexc.CommandError(error.msg)
|
|
||||||
|
|
||||||
self._open(new_url, tab, background, window)
|
|
||||||
|
|
||||||
def _navigate_up(self, url, tab, background, window):
|
|
||||||
"""Helper method for :navigate when `where' is up.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
url: The current url.
|
|
||||||
tab: Whether to open the link in a new tab.
|
|
||||||
background: Open the link in a new background tab.
|
|
||||||
window: Open the link in a new window.
|
|
||||||
"""
|
|
||||||
path = url.path()
|
|
||||||
if not path or path == '/':
|
|
||||||
raise cmdexc.CommandError("Can't go up!")
|
|
||||||
new_path = posixpath.join(path, posixpath.pardir)
|
|
||||||
url.setPath(new_path)
|
|
||||||
self._open(url, tab, background, window)
|
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||||
backend=usertypes.Backend.QtWebKit)
|
backend=usertypes.Backend.QtWebKit)
|
||||||
@cmdutils.argument('where', choices=['prev', 'next', 'up', 'increment',
|
@cmdutils.argument('where', choices=['prev', 'next', 'up', 'increment',
|
||||||
@ -506,26 +471,29 @@ class CommandDispatcher:
|
|||||||
widget = self._current_widget()
|
widget = self._current_widget()
|
||||||
url = self._current_url().adjusted(QUrl.RemoveFragment)
|
url = self._current_url().adjusted(QUrl.RemoveFragment)
|
||||||
|
|
||||||
if where in ['prev', 'next']:
|
handlers = {
|
||||||
# FIXME:qtwebengine have a proper API for this
|
'prev': functools.partial(navigate.prevnext, prev=True),
|
||||||
if widget.backend == usertypes.Backend.QtWebEngine:
|
'next': functools.partial(navigate.prevnext, prev=False),
|
||||||
raise cmdexc.CommandError(":navigate prev/next is not "
|
'up': navigate.path_up,
|
||||||
"supported yet with QtWebEngine")
|
'decrement': functools.partial(navigate.incdec,
|
||||||
|
inc_or_dec='decrement'),
|
||||||
|
'increment': functools.partial(navigate.incdec,
|
||||||
|
inc_or_dec='increment'),
|
||||||
|
}
|
||||||
|
|
||||||
hintmanager = objreg.get('hintmanager', scope='tab', tab='current')
|
try:
|
||||||
if where == 'prev':
|
if where in ['prev', 'next']:
|
||||||
hintmanager.follow_prevnext(widget, url, prev=True, tab=tab,
|
handler = handlers[where]
|
||||||
background=bg, window=window)
|
handler(browsertab=widget, win_id=self._win_id, baseurl=url,
|
||||||
elif where == 'next':
|
tab=tab, background=bg, window=window)
|
||||||
hintmanager.follow_prevnext(widget, url, prev=False, tab=tab,
|
elif where in ['up', 'increment', 'decrement']:
|
||||||
background=bg, window=window)
|
new_url = handlers[where](url)
|
||||||
elif where == 'up':
|
self._open(new_url, tab, bg, window)
|
||||||
self._navigate_up(url, tab, bg, window)
|
else: # pragma: no cover
|
||||||
elif where in ['decrement', 'increment']:
|
raise ValueError("Got called with invalid value {} for "
|
||||||
self._navigate_incdec(url, where, tab, bg, window)
|
"`where'.".format(where))
|
||||||
else: # pragma: no cover
|
except navigate.Error as e:
|
||||||
raise ValueError("Got called with invalid value {} for "
|
raise cmdexc.CommandError(e)
|
||||||
"`where'.".format(where))
|
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', hide=True,
|
@cmdutils.register(instance='command-dispatcher', hide=True,
|
||||||
scope='window')
|
scope='window')
|
||||||
|
@ -630,83 +630,6 @@ class HintManager(QObject):
|
|||||||
# Do multi-word matching
|
# Do multi-word matching
|
||||||
return all(word in elemstr for word in filterstr.split())
|
return all(word in elemstr for word in filterstr.split())
|
||||||
|
|
||||||
def _find_prevnext(self, prev, elems):
|
|
||||||
"""Find a prev/next element in the given list of elements."""
|
|
||||||
# First check for <link rel="prev(ious)|next">
|
|
||||||
rel_values = ('prev', 'previous') if prev else ('next')
|
|
||||||
for e in elems:
|
|
||||||
if e.tag_name() != 'link' or 'rel' not in e:
|
|
||||||
continue
|
|
||||||
if e['rel'] in rel_values:
|
|
||||||
log.hints.debug("Found '{}' with rel={}".format(
|
|
||||||
e.debug_text(), e['rel']))
|
|
||||||
return e
|
|
||||||
|
|
||||||
# Then check for regular links/buttons.
|
|
||||||
filterfunc = webelem.FILTERS[webelem.Group.prevnext]
|
|
||||||
elems = [e for e in elems if e.tag_name() != 'link' and filterfunc(e)]
|
|
||||||
option = 'prev-regexes' if prev else 'next-regexes'
|
|
||||||
if not elems:
|
|
||||||
return None
|
|
||||||
for regex in config.get('hints', option):
|
|
||||||
log.hints.vdebug("== Checking regex '{}'.".format(regex.pattern))
|
|
||||||
for e in elems:
|
|
||||||
text = str(e)
|
|
||||||
if not text:
|
|
||||||
continue
|
|
||||||
if regex.search(text):
|
|
||||||
log.hints.debug("Regex '{}' matched on '{}'.".format(
|
|
||||||
regex.pattern, text))
|
|
||||||
return e
|
|
||||||
else:
|
|
||||||
log.hints.vdebug("No match on '{}'!".format(text))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def follow_prevnext(self, browsertab, baseurl, prev=False, tab=False,
|
|
||||||
background=False, window=False):
|
|
||||||
"""Click a "previous"/"next" element on the page.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
browsertab: The WebKitTab/WebEngineTab of the page.
|
|
||||||
baseurl: The base URL of the current tab.
|
|
||||||
prev: True to open a "previous" link, False to open a "next" link.
|
|
||||||
tab: True to open in a new tab, False for the current tab.
|
|
||||||
background: True to open in a background tab.
|
|
||||||
window: True to open in a new window, False for the current one.
|
|
||||||
"""
|
|
||||||
def _follow_prevnext_cb(elems):
|
|
||||||
elem = self._find_prevnext(prev, elems)
|
|
||||||
word = 'prev' if prev else 'forward'
|
|
||||||
|
|
||||||
if elem is None:
|
|
||||||
message.error(self._win_id, "No {} links found!".format(word))
|
|
||||||
return
|
|
||||||
url = _resolve_url(elem, baseurl)
|
|
||||||
if url is None:
|
|
||||||
message.error(self._win_id, "No {} links found!".format(word))
|
|
||||||
return
|
|
||||||
qtutils.ensure_valid(url)
|
|
||||||
|
|
||||||
if window:
|
|
||||||
from qutebrowser.mainwindow import mainwindow
|
|
||||||
new_window = mainwindow.MainWindow()
|
|
||||||
new_window.show()
|
|
||||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
|
||||||
window=new_window.win_id)
|
|
||||||
tabbed_browser.tabopen(url, background=False)
|
|
||||||
elif tab:
|
|
||||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
|
||||||
window=self._win_id)
|
|
||||||
tabbed_browser.tabopen(url, background=background)
|
|
||||||
else:
|
|
||||||
browsertab = objreg.get('tab', scope='tab',
|
|
||||||
window=self._win_id, tab=self._tab_id)
|
|
||||||
browsertab.openurl(url)
|
|
||||||
|
|
||||||
selector = ', '.join([webelem.SELECTORS[webelem.Group.links],
|
|
||||||
webelem.SELECTORS[webelem.Group.prevnext]])
|
|
||||||
browsertab.find_all_elements(selector, _follow_prevnext_cb)
|
|
||||||
|
|
||||||
def _start_cb(self, elems):
|
def _start_cb(self, elems):
|
||||||
"""Initialize the elements and labels based on the context set."""
|
"""Initialize the elements and labels based on the context set."""
|
||||||
filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True)
|
filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True)
|
||||||
|
146
qutebrowser/browser/navigate.py
Normal file
146
qutebrowser/browser/navigate.py
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||||
|
|
||||||
|
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||||
|
#
|
||||||
|
# This file is part of qutebrowser.
|
||||||
|
#
|
||||||
|
# qutebrowser is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# qutebrowser is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Implementation of :navigate"""
|
||||||
|
|
||||||
|
import posixpath
|
||||||
|
|
||||||
|
from qutebrowser.browser.webkit import webelem
|
||||||
|
from qutebrowser.config import config
|
||||||
|
from qutebrowser.utils import (usertypes, objreg, urlutils, log, message,
|
||||||
|
qtutils)
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
|
||||||
|
"""Raised when the navigation can't be done."""
|
||||||
|
|
||||||
|
|
||||||
|
def incdec(url, inc_or_dec):
|
||||||
|
"""Helper method for :navigate when `where' is increment/decrement.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The current url.
|
||||||
|
inc_or_dec: Either 'increment' or 'decrement'.
|
||||||
|
tab: Whether to open the link in a new tab.
|
||||||
|
background: Open the link in a new background tab.
|
||||||
|
window: Open the link in a new window.
|
||||||
|
"""
|
||||||
|
segments = set(config.get('general', 'url-incdec-segments'))
|
||||||
|
try:
|
||||||
|
new_url = urlutils.incdec_number(url, inc_or_dec, segments=segments)
|
||||||
|
except urlutils.IncDecError as error:
|
||||||
|
raise Error(error.msg)
|
||||||
|
return new_url
|
||||||
|
|
||||||
|
|
||||||
|
def path_up(url):
|
||||||
|
"""Helper method for :navigate when `where' is up.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The current url.
|
||||||
|
"""
|
||||||
|
path = url.path()
|
||||||
|
if not path or path == '/':
|
||||||
|
raise Error("Can't go up!")
|
||||||
|
new_path = posixpath.join(path, posixpath.pardir)
|
||||||
|
url.setPath(new_path)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
def _find_prevnext(prev, elems):
|
||||||
|
"""Find a prev/next element in the given list of elements."""
|
||||||
|
# First check for <link rel="prev(ious)|next">
|
||||||
|
rel_values = ('prev', 'previous') if prev else ('next')
|
||||||
|
for e in elems:
|
||||||
|
if e.tag_name() != 'link' or 'rel' not in e:
|
||||||
|
continue
|
||||||
|
if e['rel'] in rel_values:
|
||||||
|
log.hints.debug("Found '{}' with rel={}".format(
|
||||||
|
e.debug_text(), e['rel']))
|
||||||
|
return e
|
||||||
|
|
||||||
|
# Then check for regular links/buttons.
|
||||||
|
filterfunc = webelem.FILTERS[webelem.Group.prevnext]
|
||||||
|
elems = [e for e in elems if e.tag_name() != 'link' and filterfunc(e)]
|
||||||
|
option = 'prev-regexes' if prev else 'next-regexes'
|
||||||
|
if not elems:
|
||||||
|
return None
|
||||||
|
for regex in config.get('hints', option):
|
||||||
|
log.hints.vdebug("== Checking regex '{}'.".format(regex.pattern))
|
||||||
|
for e in elems:
|
||||||
|
text = str(e)
|
||||||
|
if not text:
|
||||||
|
continue
|
||||||
|
if regex.search(text):
|
||||||
|
log.hints.debug("Regex '{}' matched on '{}'.".format(
|
||||||
|
regex.pattern, text))
|
||||||
|
return e
|
||||||
|
else:
|
||||||
|
log.hints.vdebug("No match on '{}'!".format(text))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def prevnext(*, browsertab, win_id, baseurl, prev=False,
|
||||||
|
tab=False, background=False, window=False):
|
||||||
|
"""Click a "previous"/"next" element on the page.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
browsertab: The WebKitTab/WebEngineTab of the page.
|
||||||
|
baseurl: The base URL of the current tab.
|
||||||
|
prev: True to open a "previous" link, False to open a "next" link.
|
||||||
|
tab: True to open in a new tab, False for the current tab.
|
||||||
|
background: True to open in a background tab.
|
||||||
|
window: True to open in a new window, False for the current one.
|
||||||
|
"""
|
||||||
|
# FIXME:qtwebengine have a proper API for this
|
||||||
|
if browsertab.backend == usertypes.Backend.QtWebEngine:
|
||||||
|
raise Error(":navigate prev/next is not supported yet with "
|
||||||
|
"QtWebEngine")
|
||||||
|
|
||||||
|
def _prevnext_cb(elems):
|
||||||
|
elem = _find_prevnext(prev, elems)
|
||||||
|
word = 'prev' if prev else 'forward'
|
||||||
|
|
||||||
|
if elem is None:
|
||||||
|
message.error(win_id, "No {} links found!".format(word))
|
||||||
|
return
|
||||||
|
url = elem.resolve_url(baseurl)
|
||||||
|
if url is None:
|
||||||
|
message.error(win_id, "No {} links found!".format(word))
|
||||||
|
return
|
||||||
|
qtutils.ensure_valid(url)
|
||||||
|
|
||||||
|
if window:
|
||||||
|
from qutebrowser.mainwindow import mainwindow
|
||||||
|
new_window = mainwindow.MainWindow()
|
||||||
|
new_window.show()
|
||||||
|
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||||
|
window=new_window.win_id)
|
||||||
|
tabbed_browser.tabopen(url, background=False)
|
||||||
|
elif tab:
|
||||||
|
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||||
|
window=win_id)
|
||||||
|
tabbed_browser.tabopen(url, background=background)
|
||||||
|
else:
|
||||||
|
browsertab.openurl(url)
|
||||||
|
|
||||||
|
selector = ', '.join([webelem.SELECTORS[webelem.Group.links],
|
||||||
|
webelem.SELECTORS[webelem.Group.prevnext]])
|
||||||
|
browsertab.find_all_elements(selector, _prevnext_cb)
|
Loading…
Reference in New Issue
Block a user