Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: 

 

# Copyright 2016-2018 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 import webelem 

from qutebrowser.config import config 

from qutebrowser.utils import objreg, urlutils, log, message, qtutils 

from qutebrowser.mainwindow import mainwindow 

 

 

class Error(Exception): 

 

"""Raised when the navigation can't be done.""" 

 

 

def incdec(url, count, inc_or_dec): 

"""Helper method for :navigate when `where' is increment/decrement. 

 

Args: 

url: The current url. 

count: How much to increment or decrement by. 

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.val.url.incdec_segments) 

try: 

new_url = urlutils.incdec_number(url, inc_or_dec, count, 

segments=segments) 

except urlutils.IncDecError as error: 

raise Error(error.msg) 

return new_url 

 

 

def path_up(url, count): 

"""Helper method for :navigate when `where' is up. 

 

Args: 

url: The current url. 

count: The number of levels to go up in the url. 

""" 

path = url.path() 

if not path or path == '/': 

raise Error("Can't go up!") 

for _i in range(0, min(count, path.count('/'))): 

path = posixpath.join(path, posixpath.pardir) 

path = posixpath.normpath(path) 

url.setPath(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() not in ['link', 'a'] or 'rel' not in e: 

continue 

if set(e['rel'].split(' ')) & rel_values: 

log.hints.debug("Found {!r} with rel={}".format(e, e['rel'])) 

return e 

 

# Then check for regular links/buttons. 

elems = [e for e in elems if e.tag_name() != 'link'] 

option = 'prev_regexes' if prev else 'next_regexes' 

if not elems: 

return None 

 

# pylint: disable=bad-config-option 

for regex in getattr(config.val.hints, option): 

# pylint: enable=bad-config-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. 

""" 

def _prevnext_cb(elems): 

if elems is None: 

message.error("There was an error while getting hint elements") 

return 

 

elem = _find_prevnext(prev, elems) 

word = 'prev' if prev else 'forward' 

 

if elem is None: 

message.error("No {} links found!".format(word)) 

return 

url = elem.resolve_url(baseurl) 

if url is None: 

message.error("No {} links found!".format(word)) 

return 

qtutils.ensure_valid(url) 

 

cur_tabbed_browser = objreg.get('tabbed-browser', scope='window', 

window=win_id) 

 

if window: 

new_window = mainwindow.MainWindow( 

private=cur_tabbed_browser.private) 

new_window.show() 

tabbed_browser = objreg.get('tabbed-browser', scope='window', 

window=new_window.win_id) 

tabbed_browser.tabopen(url, background=False) 

elif tab: 

cur_tabbed_browser.tabopen(url, background=background) 

else: 

browsertab.openurl(url) 

 

browsertab.elements.find_css(webelem.SELECTORS[webelem.Group.links], 

_prevnext_cb)