Skip to content

Commit 2c96a82

Browse files
Merge pull request #121 from stummjr/has-class-newline
[MRG+1] Fix has-class to deal with newlines in class names
2 parents a1e0e6b + 3305312 commit 2c96a82

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

parsel/xpathfuncs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
import re
12
from lxml import etree
23

34
from six import string_types
45

6+
from w3lib.html import HTML5_WHITESPACE
7+
8+
regex = '[{}]+'.format(HTML5_WHITESPACE)
9+
replace_html5_whitespaces = re.compile(regex).sub
10+
511

612
def set_xpathfunc(fname, func):
713
"""Register a custom extension function to use in XPath expressions.
@@ -48,6 +54,7 @@ def has_class(context, *classes):
4854
if node_cls is None:
4955
return False
5056
node_cls = ' ' + node_cls + ' '
57+
node_cls = replace_html5_whitespaces(' ', node_cls)
5158
for cls in classes:
5259
if ' ' + cls + ' ' not in node_cls:
5360
return False

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def has_environment_marker_platform_impl_support():
2626
return parse_version(setuptools_version) >= parse_version('18.5')
2727

2828
install_requires = [
29-
'w3lib>=1.8.0',
29+
'w3lib>=1.19.0',
3030
'lxml>=2.3',
3131
'six>=1.5.2',
3232
'cssselect>=0.9'

tests/test_xpathfuncs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ def test_has_class_uppercase(self):
7272
[x.extract() for x in sel.xpath('//p[has-class("foo")]/text()')],
7373
[u'First'])
7474

75+
def test_has_class_newline(self):
76+
body = u"""
77+
<p CLASS="foo
78+
bar">First</p>
79+
"""
80+
sel = Selector(text=body)
81+
self.assertEqual(
82+
[x.extract() for x in sel.xpath(u'//p[has-class("foo")]/text()')],
83+
[u'First'])
84+
85+
def test_has_class_tab(self):
86+
body = u"""
87+
<p CLASS="foo\tbar">First</p>
88+
"""
89+
sel = Selector(text=body)
90+
self.assertEqual(
91+
[x.extract() for x in sel.xpath(u'//p[has-class("foo")]/text()')],
92+
[u'First'])
93+
7594
def test_set_xpathfunc(self):
7695

7796
def myfunc(ctx):

0 commit comments

Comments
 (0)