diff --git a/compressor/filters/css_default.py b/compressor/filters/css_default.py index 8a05f87..efbb138 100644 --- a/compressor/filters/css_default.py +++ b/compressor/filters/css_default.py @@ -9,6 +9,7 @@ from compressor.filters import FilterBase, FilterError from compressor.utils import staticfiles URL_PATTERN = re.compile(r'url\(([^\)]+)\)') +SRC_PATTERN = re.compile(r'src=([\'"])(.+?)\1') class CssAbsoluteFilter(FilterBase): @@ -36,7 +37,8 @@ class CssAbsoluteFilter(FilterBase): 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: @@ -86,3 +88,13 @@ class CssAbsoluteFilter(FilterBase): 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) diff --git a/compressor/tests/filters.py b/compressor/tests/filters.py index df5f207..86ac67c 100644 --- a/compressor/tests/filters.py +++ b/compressor/tests/filters.py @@ -85,7 +85,8 @@ class CssMinTestCase(TestCase): class CssAbsolutizingTestCase(TestCase): hashing_method = 'mtime' hashing_func = staticmethod(get_hashed_mtime) - content = "p { background: url('../../img/python.png') }" + content = ("p { background: url('../../img/python.png') }" + "p { filter: Alpha(src='../../img/python.png') }") def setUp(self): self.old_enabled = settings.COMPRESS_ENABLED @@ -108,36 +109,54 @@ class CssAbsolutizingTestCase(TestCase): def test_css_absolute_filter(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + params = { + 'url': settings.COMPRESS_URL, + 'hash': self.hashing_func(imagefilename), + } + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) - settings.COMPRESS_URL = 'http://media.example.com/' + settings.COMPRESS_URL = params['url'] = 'http://media.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_https(self): filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + params = { + 'url': settings.COMPRESS_URL, + 'hash': self.hashing_func(imagefilename), + } + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) - settings.COMPRESS_URL = 'https://media.example.com/' + settings.COMPRESS_URL = params['url'] = 'https://media.example.com/' filter = CssAbsoluteFilter(self.content) filename = os.path.join(settings.COMPRESS_ROOT, 'css/url/test.css') - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_absolute_filter_relative_path(self): filename = os.path.join(settings.TEST_DIR, 'whatever', '..', 'media', 'whatever/../css/url/test.css') imagefilename = os.path.join(settings.COMPRESS_ROOT, 'img/python.png') - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + params = { + 'url': settings.COMPRESS_URL, + 'hash': self.hashing_func(imagefilename), + } + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params filter = CssAbsoluteFilter(self.content) self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) - settings.COMPRESS_URL = 'https://media.example.com/' + settings.COMPRESS_URL = params['url'] = 'https://media.example.com/' filter = CssAbsoluteFilter(self.content) - output = "p { background: url('%simg/python.png?%s') }" % (settings.COMPRESS_URL, self.hashing_func(imagefilename)) + output = ("p { background: url('%(url)simg/python.png?%(hash)s') }" + "p { filter: Alpha(src='%(url)simg/python.png?%(hash)s') }") % params self.assertEqual(output, filter.input(filename=filename, basename='css/url/test.css')) def test_css_hunks(self): @@ -150,12 +169,14 @@ p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } p { background: url('/media/img/python.png?%(hash1)s'); } +p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/python.png?%(hash1)s'); } """ % hash_dict, u"""\ p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } p { background: url('/media/img/add.png?%(hash2)s'); } +p { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/media/img/add.png?%(hash2)s'); } """ % hash_dict], list(self.css_node.hunks())) def test_guess_filename(self): diff --git a/compressor/tests/media/css/url/2/url2.css b/compressor/tests/media/css/url/2/url2.css index 48e20a5..45686ca 100644 --- a/compressor/tests/media/css/url/2/url2.css +++ b/compressor/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'); } diff --git a/compressor/tests/media/css/url/url1.css b/compressor/tests/media/css/url/url1.css index e77e922..609c111 100644 --- a/compressor/tests/media/css/url/url1.css +++ b/compressor/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'); }