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:
parent
d50a08d159
commit
203a5dff74
@ -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
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -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)))
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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."""
|
||||||
|
13
tests/end2end/data/hints/html/javascript.html
Normal file
13
tests/end2end/data/hints/html/javascript.html
Normal 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>
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user