Make CssAbsoluteFilter replace src="..." patterns with absolute paths #126

Closed
wants to merge 7 commits into
from
View
16 compressor/filters/css_default.py
@@ -8,6 +8,7 @@
from compressor.utils import staticfiles
URL_PATTERN = re.compile(r'url\(([^\)]+)\)')
+SRC_PATTERN = re.compile(r'src=([\'"])(.+?)\1')
class CssAbsoluteFilter(FilterBase):
@@ -35,7 +36,8 @@ def input(self, filename=None, basename=None, **kwargs):
self.protocol = '%s/' % '/'.join(parts[:2])
self.host = parts[2]
self.directory_name = '/'.join((self.url, os.path.dirname(self.path)))
- return URL_PATTERN.sub(self.url_converter, self.content)
+ return SRC_PATTERN.sub(self.src_converter,
+ URL_PATTERN.sub(self.url_converter, self.content))
def find(self, basename):
if settings.DEBUG and basename and staticfiles.finders:
@@ -62,7 +64,7 @@ def add_suffix(self, url):
if settings.COMPRESS_CSS_HASHING_METHOD == "mtime":
suffix = get_hashed_mtime(filename)
elif settings.COMPRESS_CSS_HASHING_METHOD == "hash":
- hash_file = open(filename)
+ hash_file = open(filename, 'rb')
try:
suffix = get_hexdigest(hash_file.read(), 12)
finally:
@@ -89,3 +91,13 @@ def url_converter(self, matchobj):
if self.has_scheme:
full_url = "%s%s" % (self.protocol, full_url)
return "url('%s')" % self.add_suffix(full_url)
+
+ def src_converter(self, matchobj):
+ url = matchobj.group(2)
+ url = url.strip(' \'"')
+ if url.startswith(('http://', 'https://', '/', 'data:')):
+ return "src='%s'" % self.add_suffix(url)
+ full_url = posixpath.normpath('/'.join([str(self.directory_name), url]))
+ if self.has_scheme:
+ full_url = "%s%s" % (self.protocol, full_url)
+ return "src='%s'" % self.add_suffix(full_url)
View
1 tests/media/css/url/2/url2.css
@@ -2,3 +2,4 @@ p { background: url('../../../img/add.png'); }
p { background: url(../../../img/add.png); }
p { background: url( ../../../img/add.png ); }
p { background: url( '../../../img/add.png' ); }
+p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../../../img/add.png'); }
View
1 tests/media/css/url/url1.css
@@ -2,3 +2,4 @@ p { background: url('../../img/python.png'); }
p { background: url(../../img/python.png); }
p { background: url( ../../img/python.png ); }
p { background: url( '../../img/python.png' ); }
+p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../../img/python.png'); }
View
25 tests/tests/filters.py
@@ -104,11 +104,18 @@ def test_css_absolute_filter(self):
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
filter = CssAbsoluteFilter(content)
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ content2 = "p { filter: Alpha(src='../../img/python.png') }"
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ filter = CssAbsoluteFilter(content2)
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
settings.COMPRESS_URL = 'http://media.example.com/'
filter = CssAbsoluteFilter(content)
filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css')
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ filter = CssAbsoluteFilter(content2)
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
def test_css_absolute_filter_https(self):
from compressor.filters.css_default import CssAbsoluteFilter
@@ -118,11 +125,18 @@ def test_css_absolute_filter_https(self):
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
filter = CssAbsoluteFilter(content)
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ content2 = "p { filter: Alpha(src='../../img/python.png') }"
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ filter = CssAbsoluteFilter(content2)
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
settings.COMPRESS_URL = 'https://media.example.com/'
filter = CssAbsoluteFilter(content)
filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css')
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ filter = CssAbsoluteFilter(content2)
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
def test_css_absolute_filter_relative_path(self):
from compressor.filters.css_default import CssAbsoluteFilter
@@ -132,18 +146,25 @@ def test_css_absolute_filter_relative_path(self):
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
filter = CssAbsoluteFilter(content)
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ content2 = "p { filter: Alpha(src='../../img/python.png') }"
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ filter = CssAbsoluteFilter(content2)
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
settings.COMPRESS_URL = 'https://media.example.com/'
filter = CssAbsoluteFilter(content)
output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css'))
+ filter = CssAbsoluteFilter(content2)
+ output2 = "p { filter: Alpha(src='%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.suffix_method(imagefilename))
+ self.assertEqual(output2, filter.input(filename=filename, basename='css/url/test.css'))
def test_css_hunks(self):
hash_dict = {
'hash1': self.suffix_method(os.path.join(settings.COMPRESS_ROOT, 'img/python.png')),
'hash2': self.suffix_method(os.path.join(settings.COMPRESS_ROOT, 'img/add.png')),
}
- out = [u"p { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\n" % hash_dict,
- u"p { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\n" % hash_dict]
+ out = [u"p { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { background: url('/media/img/python.png?%(hash1)s'); }\np { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/python.png?%(hash1)s'); }\n" % hash_dict,
+ u"p { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { background: url('/media/img/add.png?%(hash2)s'); }\np { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/add.png?%(hash2)s'); }\n" % hash_dict]
hunks = [h for m, h in self.css_node.hunks()]
self.assertEqual(out, hunks)