Merge branch 'Kingdread-master'
This commit is contained in:
commit
06a82c5566
@ -60,6 +60,8 @@ Fixed
|
|||||||
- Fixed entering of insert mode when certain disabled text fields were clicked.
|
- Fixed entering of insert mode when certain disabled text fields were clicked.
|
||||||
- Fixed a crash when using `:set` with `-p` and `!` (invert value)
|
- Fixed a crash when using `:set` with `-p` and `!` (invert value)
|
||||||
- Downloads with unknown size are now handled correctly.
|
- Downloads with unknown size are now handled correctly.
|
||||||
|
- `:navigate increment/decrement` (`<Ctrl-A>`/`<Ctrl-X>`) now handles some
|
||||||
|
corner-cases better.
|
||||||
|
|
||||||
Removed
|
Removed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
@ -146,6 +146,7 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* ZDarian
|
* ZDarian
|
||||||
* Peter Vilim
|
* Peter Vilim
|
||||||
* John ShaggyTwoDope Jenkins
|
* John ShaggyTwoDope Jenkins
|
||||||
|
* Daniel
|
||||||
* Jimmy
|
* Jimmy
|
||||||
* Alexander Cogneau
|
* Alexander Cogneau
|
||||||
* Zach-Button
|
* Zach-Button
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
"""Command dispatcher for TabbedBrowser."""
|
"""Command dispatcher for TabbedBrowser."""
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import posixpath
|
import posixpath
|
||||||
@ -472,29 +471,10 @@ class CommandDispatcher:
|
|||||||
background: Open the link in a new background tab.
|
background: Open the link in a new background tab.
|
||||||
window: Open the link in a new window.
|
window: Open the link in a new window.
|
||||||
"""
|
"""
|
||||||
encoded = bytes(url.toEncoded()).decode('ascii')
|
|
||||||
# Get the last number in a string
|
|
||||||
match = re.match(r'(.*\D|^)(\d+)(.*)', encoded)
|
|
||||||
if not match:
|
|
||||||
raise cmdexc.CommandError("No number found in URL!")
|
|
||||||
pre, number, post = match.groups()
|
|
||||||
if not number:
|
|
||||||
raise cmdexc.CommandError("No number found in URL!")
|
|
||||||
try:
|
try:
|
||||||
val = int(number)
|
new_url = urlutils.incdec_number(url, incdec)
|
||||||
except ValueError:
|
except urlutils.IncDecError as error:
|
||||||
raise cmdexc.CommandError("Could not parse number '{}'.".format(
|
raise cmdexc.CommandError(error.msg)
|
||||||
number))
|
|
||||||
if incdec == 'decrement':
|
|
||||||
if val <= 0:
|
|
||||||
raise cmdexc.CommandError("Can't decrement {}!".format(val))
|
|
||||||
val -= 1
|
|
||||||
elif incdec == 'increment':
|
|
||||||
val += 1
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid value {} for indec!".format(incdec))
|
|
||||||
urlstr = ''.join([pre, str(val), post]).encode('ascii')
|
|
||||||
new_url = QUrl.fromEncoded(urlstr)
|
|
||||||
self._open(new_url, tab, background, window)
|
self._open(new_url, tab, background, window)
|
||||||
|
|
||||||
def _navigate_up(self, url, tab, background, window):
|
def _navigate_up(self, url, tab, background, window):
|
||||||
|
@ -443,3 +443,59 @@ class FuzzyUrlError(Exception):
|
|||||||
return self.msg
|
return self.msg
|
||||||
else:
|
else:
|
||||||
return '{}: {}'.format(self.msg, self.url.errorString())
|
return '{}: {}'.format(self.msg, self.url.errorString())
|
||||||
|
|
||||||
|
|
||||||
|
class IncDecError(Exception):
|
||||||
|
|
||||||
|
"""Exception raised by incdec_number on problems.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
msg: The error message.
|
||||||
|
url: The QUrl which caused the error.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, msg, url):
|
||||||
|
super().__init__(msg)
|
||||||
|
self.url = url
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{}: {}'.format(self.msg, self.url.toString())
|
||||||
|
|
||||||
|
|
||||||
|
def incdec_number(url, incdec):
|
||||||
|
"""Find a number in the url and increment or decrement it.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The current url
|
||||||
|
incdec: Either 'increment' or 'decrement'
|
||||||
|
|
||||||
|
Return:
|
||||||
|
The new url with the number incremented/decremented.
|
||||||
|
|
||||||
|
Raises IncDecError if the url contains no number.
|
||||||
|
"""
|
||||||
|
if not url.isValid():
|
||||||
|
raise ValueError(get_errstring(url))
|
||||||
|
|
||||||
|
path = url.path()
|
||||||
|
# Get the last number in a string
|
||||||
|
match = re.match(r'(.*\D|^)(\d+)(.*)', path)
|
||||||
|
if not match:
|
||||||
|
raise IncDecError("No number found in URL!", url)
|
||||||
|
pre, number, post = match.groups()
|
||||||
|
# This should always succeed because we match \d+
|
||||||
|
val = int(number)
|
||||||
|
if incdec == 'decrement':
|
||||||
|
if val <= 0:
|
||||||
|
raise IncDecError("Can't decrement {}!".format(val), url)
|
||||||
|
val -= 1
|
||||||
|
elif incdec == 'increment':
|
||||||
|
val += 1
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid value {} for indec!".format(incdec))
|
||||||
|
new_path = ''.join([pre, str(val), post])
|
||||||
|
# Make a copy of the QUrl so we don't modify the original
|
||||||
|
new_url = QUrl(url)
|
||||||
|
new_url.setPath(new_path)
|
||||||
|
return new_url
|
||||||
|
@ -524,3 +524,70 @@ def test_same_domain_invalid_url(url1, url2):
|
|||||||
"""Test same_domain with invalid URLs."""
|
"""Test same_domain with invalid URLs."""
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
urlutils.same_domain(QUrl(url1), QUrl(url2))
|
urlutils.same_domain(QUrl(url1), QUrl(url2))
|
||||||
|
|
||||||
|
class TestIncDecNumber:
|
||||||
|
|
||||||
|
"""Tests for urlutils.incdec_number()."""
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url, incdec, output', [
|
||||||
|
("http://example.com/index1.html", "increment", "http://example.com/index2.html"),
|
||||||
|
("http://foo.bar/folder_1/image_2", "increment", "http://foo.bar/folder_1/image_3"),
|
||||||
|
("http://bbc.c0.uk:80/story_1", "increment", "http://bbc.c0.uk:80/story_2"),
|
||||||
|
("http://mydomain.tld/1_%C3%A4", "increment", "http://mydomain.tld/2_%C3%A4"),
|
||||||
|
("http://example.com/site/5#5", "increment", "http://example.com/site/6#5"),
|
||||||
|
|
||||||
|
("http://example.com/index10.html", "decrement", "http://example.com/index9.html"),
|
||||||
|
("http://foo.bar/folder_1/image_3", "decrement", "http://foo.bar/folder_1/image_2"),
|
||||||
|
("http://bbc.c0.uk:80/story_1", "decrement", "http://bbc.c0.uk:80/story_0"),
|
||||||
|
("http://mydomain.tld/2_%C3%A4", "decrement", "http://mydomain.tld/1_%C3%A4"),
|
||||||
|
("http://example.com/site/5#5", "decrement", "http://example.com/site/4#5"),
|
||||||
|
])
|
||||||
|
def test_incdec_number(self, url, incdec, output):
|
||||||
|
"""Test incdec_number with valid URLs."""
|
||||||
|
new_url = urlutils.incdec_number(QUrl(url), incdec)
|
||||||
|
assert new_url == QUrl(output)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url', [
|
||||||
|
"http://example.com/long/path/but/no/number",
|
||||||
|
"http://ex4mple.com/number/in/hostname",
|
||||||
|
"http://example.com:42/number/in/port",
|
||||||
|
"http://www2.example.com/number/in/subdomain",
|
||||||
|
"http://example.com/%C3%B6/urlencoded/data",
|
||||||
|
"http://example.com/number/in/anchor#5",
|
||||||
|
"http://www2.ex4mple.com:42/all/of/the/%C3%A4bove#5",
|
||||||
|
])
|
||||||
|
def test_no_number(self, url):
|
||||||
|
"""Test incdec_number with URLs that don't contain a number."""
|
||||||
|
with pytest.raises(urlutils.IncDecError):
|
||||||
|
urlutils.incdec_number(QUrl(url), "increment")
|
||||||
|
|
||||||
|
def test_number_below_0(self):
|
||||||
|
"""Test incdec_number with a number that would be below zero
|
||||||
|
after decrementing."""
|
||||||
|
with pytest.raises(urlutils.IncDecError):
|
||||||
|
urlutils.incdec_number(QUrl('http://example.com/page_0.html'),
|
||||||
|
'decrement')
|
||||||
|
|
||||||
|
def test_invalid_url(self):
|
||||||
|
"""Test if incdec_number rejects an invalid URL."""
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
urlutils.incdec_number(QUrl(""), "increment")
|
||||||
|
|
||||||
|
def test_wrong_mode(self):
|
||||||
|
"""Test if incdec_number rejects a wrong parameter for the incdec
|
||||||
|
argument."""
|
||||||
|
valid_url = QUrl("http://example.com/0")
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
urlutils.incdec_number(valid_url, "foobar")
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("url, msg, expected_str", [
|
||||||
|
("http://example.com", "Invalid", "Invalid: http://example.com"),
|
||||||
|
])
|
||||||
|
def test_incdec_error(self, url, msg, expected_str):
|
||||||
|
"""Test IncDecError."""
|
||||||
|
url = QUrl(url)
|
||||||
|
with pytest.raises(urlutils.IncDecError) as excinfo:
|
||||||
|
raise urlutils.IncDecError(msg, url)
|
||||||
|
|
||||||
|
assert excinfo.value.url == url
|
||||||
|
assert str(excinfo.value) == expected_str
|
||||||
|
Loading…
Reference in New Issue
Block a user