Move hints._resolve_url to a WebElement method

This commit is contained in:
Florian Bruhin 2016-08-05 17:09:52 +02:00
parent 4541f19195
commit 7a65559cce
3 changed files with 45 additions and 31 deletions

View File

@ -58,32 +58,6 @@ def on_mode_entered(mode, win_id):
modeman.maybe_leave(win_id, usertypes.KeyMode.hint, 'insert mode') modeman.maybe_leave(win_id, usertypes.KeyMode.hint, 'insert mode')
def _resolve_url(elem, baseurl):
"""Resolve a URL and check if we want to keep it.
Args:
elem: The QWebElement to get the URL of.
baseurl: The baseurl of the current tab.
Return:
A QUrl with the absolute URL, or None.
"""
for attr in ['href', 'src']:
if attr in elem:
text = elem[attr].strip()
break
else:
return None
url = QUrl(text)
if not url.isValid():
return None
if url.isRelative():
url = baseurl.resolved(url)
qtutils.ensure_valid(url)
return url
class HintContext: class HintContext:
"""Context namespace used for hinting. """Context namespace used for hinting.
@ -274,7 +248,7 @@ class HintActions(QObject):
elem: The QWebElement to download. elem: The QWebElement to download.
_context: The HintContext to use. _context: The HintContext to use.
""" """
url = _resolve_url(elem, context.baseurl) url = elem.resolve_url(context.baseurl)
if url is None: if url is None:
raise HintingError raise HintingError
if context.rapid: if context.rapid:
@ -301,7 +275,7 @@ class HintActions(QObject):
'QUTE_SELECTED_TEXT': str(elem), 'QUTE_SELECTED_TEXT': str(elem),
'QUTE_SELECTED_HTML': elem.outer_xml(), 'QUTE_SELECTED_HTML': elem.outer_xml(),
} }
url = _resolve_url(elem, context.baseurl) url = elem.resolve_url(context.baseurl)
if url is not None: if url is not None:
env['QUTE_URL'] = url.toString(QUrl.FullyEncoded) env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
@ -1012,7 +986,7 @@ class HintManager(QObject):
handler = functools.partial(elem_handlers[self._context.target], handler = functools.partial(elem_handlers[self._context.target],
elem, self._context) elem, self._context)
elif self._context.target in url_handlers: elif self._context.target in url_handlers:
url = _resolve_url(elem, self._context.baseurl) url = elem.resolve_url(self._context.baseurl)
if url is None: if url is None:
self._show_url_error() self._show_url_error()
return return

View File

@ -33,7 +33,7 @@ from PyQt5.QtCore import QRect, QUrl
from PyQt5.QtWebKit import QWebElement from PyQt5.QtWebKit import QWebElement
from qutebrowser.config import config from qutebrowser.config import config
from qutebrowser.utils import log, usertypes, utils, javascript from qutebrowser.utils import log, usertypes, utils, javascript, qtutils
Group = usertypes.enum('Group', ['all', 'links', 'images', 'url', 'prevnext', Group = usertypes.enum('Group', ['all', 'links', 'images', 'url', 'prevnext',
@ -500,6 +500,30 @@ class WebElementWrapper(collections.abc.MutableMapping):
visible_in_frame = visible_on_screen visible_in_frame = visible_on_screen
return all([visible_on_screen, visible_in_frame]) return all([visible_on_screen, visible_in_frame])
def resolve_url(self, baseurl):
"""Resolve the URL in the element's src/href attribute.
Args:
baseurl: The URL to base relative URLs on as QUrl.
Return:
A QUrl with the absolute URL, or None.
"""
for attr in ['href', 'src']:
if attr in self:
text = self[attr].strip()
break
else:
return None
url = QUrl(text)
if not url.isValid():
return None
if url.isRelative():
url = baseurl.resolved(url)
qtutils.ensure_valid(url)
return url
def get_child_frames(startframe): def get_child_frames(startframe):
"""Get all children recursively of a given QWebFrame. """Get all children recursively of a given QWebFrame.

View File

@ -24,7 +24,7 @@ import collections.abc
import operator import operator
import itertools import itertools
from PyQt5.QtCore import QRect, QPoint from PyQt5.QtCore import QRect, QPoint, QUrl
from PyQt5.QtWebKit import QWebElement from PyQt5.QtWebKit import QWebElement
import pytest import pytest
@ -942,3 +942,19 @@ class TestIsEditable:
stubbed_config.data['input']['insert-mode-on-plugins'] = setting stubbed_config.data['input']['insert-mode-on-plugins'] = setting
elem = get_webelem(tagname=tagname, attributes=attributes) elem = get_webelem(tagname=tagname, attributes=attributes)
assert elem.is_editable() == editable assert elem.is_editable() == editable
@pytest.mark.parametrize('attributes, expected', [
# No attributes
({}, None),
({'href': 'foo'}, QUrl('http://www.example.com/foo')),
({'src': 'foo'}, QUrl('http://www.example.com/foo')),
({'href': 'foo', 'src': 'bar'}, QUrl('http://www.example.com/foo')),
({'href': '::garbage::'}, None),
({'href': 'http://www.example.org/'}, QUrl('http://www.example.org/')),
({'href': ' foo '}, QUrl('http://www.example.com/foo')),
])
def test_resolve_url(attributes, expected):
elem = get_webelem(attributes=attributes)
baseurl = QUrl('http://www.example.com/')
assert elem.resolve_url(baseurl) == expected