diff --git a/apps/amo/helpers.py b/apps/amo/helpers.py index ecebd03a4845..b4807fca7955 100644 --- a/apps/amo/helpers.py +++ b/apps/amo/helpers.py @@ -19,6 +19,8 @@ from jingo import register, env # Needed to make sure our own |f filter overrides jingo's one. from jingo import helpers # noqa +from jingo_minify.helpers import (_build_html, _get_compiled_css_url, get_path, + is_external) from tower import ugettext as _, strip_whitespace import amo @@ -600,3 +602,54 @@ def f(string, *args, **kwargs): if not isinstance(string, six.text_type): string = six.text_type(string) return string.format(*args, **kwargs) + + +def _relative_to_absolute(url): + """ + Prepends relative URLs with MEDIA_URL to turn those inline-able. + This method is intended to be used as a ``replace`` parameter of + ``re.sub``. + """ + url = url.group(1).strip('"\'') + if not url.startswith(('data:', 'http:', 'https:', '//')): + url = url.replace('../../', settings.MEDIA_URL) + return 'url(%s)' % url + + +@register.function +def inline_css(bundle, media=False, debug=None): + """ + If we are in debug mode, just output a single style tag for each css file. + If we are not in debug mode, return a style that contains bundle-min.css. + Forces a regular css() call for external URLs (no inline allowed). + + Extracted from jingo-minify and re-registered, see: + https://github.com/jsocol/jingo-minify/pull/41 + Added: turns relative links to absolute ones using MEDIA_URL. + """ + if debug is None: + debug = getattr(settings, 'TEMPLATE_DEBUG', False) + + if debug: + items = [_get_compiled_css_url(i) + for i in settings.MINIFY_BUNDLES['css'][bundle]] + else: + items = ['css/%s-min.css' % bundle] + + if not media: + media = getattr(settings, 'CSS_MEDIA_DEFAULT', 'screen,projection,tv') + + contents = [] + for css in items: + if is_external(css): + return _build_html([css], '' % media) + with open(get_path(css), 'r') as f: + css_content = f.read() + css_parsed = re.sub(r'url\(([^)]*?)\)', + _relative_to_absolute, + css_content) + contents.append(css_parsed) + + return _build_html(contents, '' % media) diff --git a/apps/amo/tests/test_helpers.py b/apps/amo/tests/test_helpers.py index 7e1b75a8d0a0..ac486c587d60 100644 --- a/apps/amo/tests/test_helpers.py +++ b/apps/amo/tests/test_helpers.py @@ -11,7 +11,7 @@ import jingo import test_utils from mock import Mock, patch -from nose.tools import eq_ +from nose.tools import eq_, ok_ from pyquery import PyQuery import amo @@ -464,3 +464,11 @@ def test_f(): # This makes sure there's no UnicodeEncodeError when doing the string # interpolation. eq_(render(u'{{ "foo {0}"|f("baré") }}'), u'foo baré') + + +def test_inline_css(): + jingo.load_helpers() + env = jingo.env + t = env.from_string("{{ inline_css('zamboni/mobile', debug=True) }}") + s = t.render() + ok_('background-image: url(/media/img/icons/stars.png);' in s)