From 483c201bd754ef27ebe65447d1b881725ddebce6 Mon Sep 17 00:00:00 2001 From: Jonas Date: Mon, 26 Sep 2011 10:20:01 +0200 Subject: [PATCH 1/2] Make CssAbsoluteFilter replace src="..." patterns with absolute paths The workarounds for many CSS3 properties in IE use proprietary "Filter" expressions. These often need a "src" variable with an image path. For some reason, that path is intepreted as relative to the HTML file including the CSS, not the CSS file itself. This patch makes those paths absolute as well. --- compressor/filters/css_default.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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) From 0136c3b92f4289c01d8b1ad847010fbd80b953f3 Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 8 Feb 2012 10:28:58 +0100 Subject: [PATCH 2/2] Add tests for previous commit (issue #126) --- compressor/tests/filters.py | 41 +++++++++++++++++------ compressor/tests/media/css/url/2/url2.css | 1 + compressor/tests/media/css/url/url1.css | 1 + 3 files changed, 33 insertions(+), 10 deletions(-) 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'); }