Get rid of webelem.FILTERS

There's actually no good reason to filter javascript links as we might want to
click them (or copy their URL) just like any other link - this fixes #2404.

With that being gone, we don't need FILTERS at all anymore, as we can check for
existence of the href attribute in the CSS selector instead.
This commit is contained in:
Florian Bruhin 2017-05-12 09:13:19 +02:00
parent d50a08d159
commit 203a5dff74
7 changed files with 27 additions and 28 deletions

View File

@ -54,6 +54,7 @@ Changed
a restart. a restart.
- The adblocker now also blocks non-GET requests (e.g. POST) - The adblocker now also blocks non-GET requests (e.g. POST)
- `:follow-selected` now also works with QtWebEngine - `:follow-selected` now also works with QtWebEngine
- javascript: links can now be hinted
Fixed Fixed
~~~~~ ~~~~~

View File

@ -579,12 +579,10 @@ class HintManager(QObject):
if elems is None: if elems is None:
message.error("There was an error while getting hint elements") message.error("There was an error while getting hint elements")
return return
filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True)
elems = [e for e in elems if filterfunc(e)]
if not elems: if not elems:
message.error("No elements found.") message.error("No elements found.")
return return
strings = self._hint_strings(elems) strings = self._hint_strings(elems)
log.hints.debug("hints: {}".format(', '.join(strings))) log.hints.debug("hints: {}".format(', '.join(strings)))

View File

@ -79,8 +79,7 @@ def _find_prevnext(prev, elems):
return e return e
# Then check for regular links/buttons. # Then check for regular links/buttons.
filterfunc = webelem.FILTERS[webelem.Group.prevnext] elems = [e for e in elems if e.tag_name() != 'link']
elems = [e for e in elems if e.tag_name() != 'link' and filterfunc(e)]
option = 'prev-regexes' if prev else 'next-regexes' option = 'prev-regexes' if prev else 'next-regexes'
if not elems: if not elems:
return None return None

View File

@ -22,9 +22,6 @@
Module attributes: Module attributes:
Group: Enum for different kinds of groups. Group: Enum for different kinds of groups.
SELECTORS: CSS selectors for different groups of elements. SELECTORS: CSS selectors for different groups of elements.
FILTERS: A dictionary of filter functions for the modes.
The filter for "links" filters javascript:-links and a-tags
without "href".
""" """
import collections.abc import collections.abc
@ -45,10 +42,11 @@ SELECTORS = {
Group.all: ('a, area, textarea, select, input:not([type=hidden]), button, ' Group.all: ('a, area, textarea, select, input:not([type=hidden]), button, '
'frame, iframe, link, [onclick], [onmousedown], [role=link], ' 'frame, iframe, link, [onclick], [onmousedown], [role=link], '
'[role=option], [role=button], img'), '[role=option], [role=button], img'),
Group.links: 'a, area, link, [role=link]', Group.links: 'a[href], area[href], link[href], [role=link][href]',
Group.images: 'img', Group.images: 'img',
Group.url: '[src], [href]', Group.url: '[src], [href]',
Group.prevnext: 'a, area, button, link, [role=button]', Group.prevnext: 'a[href], area[href], button[href], link[href], '
'[role=button][href]',
Group.inputs: ('input[type=text], input[type=email], input[type=url], ' Group.inputs: ('input[type=text], input[type=email], input[type=url], '
'input[type=tel], input[type=number], ' 'input[type=tel], input[type=number], '
'input[type=password], input[type=search], ' 'input[type=password], input[type=search], '
@ -56,16 +54,6 @@ SELECTORS = {
} }
def filter_links(elem):
return 'href' in elem and QUrl(elem['href']).scheme() != 'javascript'
FILTERS = {
Group.links: filter_links,
Group.prevnext: filter_links,
}
class Error(Exception): class Error(Exception):
"""Base class for WebElement errors.""" """Base class for WebElement errors."""

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<!-- target: hello.txt -->
<html>
<head>
<meta charset="utf-8">
<title>Javascript link</title>
</head>
<body>
<a href="javascript:window.location.href='/data/hello.txt'" id="link">Follow me via JS!</a>
</body>
</html>

View File

@ -114,6 +114,12 @@ Feature: Using hints
And I hint with args "links yank" and follow a And I hint with args "links yank" and follow a
Then the clipboard should contain "nobody" Then the clipboard should contain "nobody"
Scenario: Yanking javascript link to clipboard
When I run :debug-set-fake-clipboard
And I open data/hints/html/javascript.html
And I hint with args "links yank" and follow a
Then the clipboard should contain "javascript:window.location.href='/data/hello.txt'"
Scenario: Rapid hinting Scenario: Rapid hinting
When I open data/hints/rapid.html in a new tab When I open data/hints/rapid.html in a new tab
And I run :tab-only And I run :tab-only

View File

@ -149,19 +149,17 @@ class SelectionAndFilterTests:
('<a href="foo" />', [webelem.Group.all, webelem.Group.links, ('<a href="foo" />', [webelem.Group.all, webelem.Group.links,
webelem.Group.prevnext, webelem.Group.url]), webelem.Group.prevnext, webelem.Group.url]),
('<a href="javascript://foo" />', [webelem.Group.all, ('<a href="javascript://foo" />', [webelem.Group.all,
webelem.Group.links,
webelem.Group.prevnext,
webelem.Group.url]), webelem.Group.url]),
('<area />', [webelem.Group.all]), ('<area />', [webelem.Group.all]),
('<area href="foo" />', [webelem.Group.all, webelem.Group.links, ('<area href="foo" />', [webelem.Group.all, webelem.Group.links,
webelem.Group.prevnext, webelem.Group.url]), webelem.Group.prevnext, webelem.Group.url]),
('<area href="javascript://foo" />', [webelem.Group.all,
webelem.Group.url]),
('<link />', [webelem.Group.all]), ('<link />', [webelem.Group.all]),
('<link href="foo" />', [webelem.Group.all, webelem.Group.links, ('<link href="foo" />', [webelem.Group.all, webelem.Group.links,
webelem.Group.prevnext, webelem.Group.url]), webelem.Group.prevnext, webelem.Group.url]),
('<link href="javascript://foo" />', [webelem.Group.all,
webelem.Group.url]),
('<textarea />', [webelem.Group.all, webelem.Group.inputs]), ('<textarea />', [webelem.Group.all, webelem.Group.inputs]),
('<select />', [webelem.Group.all]), ('<select />', [webelem.Group.all]),
@ -180,8 +178,6 @@ class SelectionAndFilterTests:
('<button />', [webelem.Group.all]), ('<button />', [webelem.Group.all]),
('<button href="foo" />', [webelem.Group.all, webelem.Group.prevnext, ('<button href="foo" />', [webelem.Group.all, webelem.Group.prevnext,
webelem.Group.url]), webelem.Group.url]),
('<button href="javascript://foo" />', [webelem.Group.all,
webelem.Group.url]),
# We can't easily test <frame>/<iframe> as they vanish when setting # We can't easily test <frame>/<iframe> as they vanish when setting
# them via QWebFrame::setHtml... # them via QWebFrame::setHtml...
@ -224,8 +220,6 @@ class TestSelectorsAndFilters:
assert len(webframe.findAllElements('*')) == 3 assert len(webframe.findAllElements('*')) == 3
elems = webframe.findAllElements(webelem.SELECTORS[group]) elems = webframe.findAllElements(webelem.SELECTORS[group])
elems = [webkitelem.WebKitElement(e, tab=None) for e in elems] elems = [webkitelem.WebKitElement(e, tab=None) for e in elems]
filterfunc = webelem.FILTERS.get(group, lambda e: True)
elems = [e for e in elems if filterfunc(e)]
assert bool(elems) == matching assert bool(elems) == matching