diff --git a/compressor/css.py b/compressor/css.py index e10697b..45cdcd2 100644 --- a/compressor/css.py +++ b/compressor/css.py @@ -34,7 +34,7 @@ class CssCompressor(Compressor): self.media_nodes[-1][1].split_content.append(data) else: node = self.__class__(content=self.parser.elem_str(elem), - context=self.context) + context=self.context) node.split_content.append(data) self.media_nodes.append((media, node)) return self.split_content diff --git a/compressor/js.py b/compressor/js.py index b087804..b1234a7 100644 --- a/compressor/js.py +++ b/compressor/js.py @@ -12,14 +12,42 @@ class JsCompressor(Compressor): def split_contents(self): if self.split_content: return self.split_content + self.extra_nodes = [] for elem in self.parser.js_elems(): attribs = self.parser.elem_attribs(elem) if 'src' in attribs: basename = self.get_basename(attribs['src']) filename = self.get_filename(basename) content = (SOURCE_FILE, filename, basename, elem) - self.split_content.append(content) else: - content = self.parser.elem_content(elem) - self.split_content.append((SOURCE_HUNK, content, None, elem)) + content = (SOURCE_HUNK, self.parser.elem_content(elem), None, elem) + self.split_content.append(content) + if 'async' in attribs: + extra = ' async' + elif 'defer' in attribs: + extra = ' defer' + else: + extra = '' + # Append to the previous node if it had the same attribute + append_to_previous = (self.extra_nodes and + self.extra_nodes[-1][0] == extra) + if append_to_previous and settings.COMPRESS_ENABLED: + self.extra_nodes[-1][1].split_content.append(content) + else: + node = self.__class__(content=self.parser.elem_str(elem), + context=self.context) + node.split_content.append(content) + self.extra_nodes.append((extra, node)) return self.split_content + + def output(self, *args, **kwargs): + if (settings.COMPRESS_ENABLED or settings.COMPRESS_PRECOMPILERS or + kwargs.get('forced', False)): + self.split_contents() + if hasattr(self, 'nodes'): + ret = [] + for extra, subnode in self.extra_nodes: + subnode.extra_context.update({'extra': extra}) + ret.append(subnode.output(*args, **kwargs)) + return '\n'.join(ret) + return super(JsCompressor, self).output(*args, **kwargs) diff --git a/compressor/templates/compressor/js_file.html b/compressor/templates/compressor/js_file.html index 09d6a9b..e76d860 100644 --- a/compressor/templates/compressor/js_file.html +++ b/compressor/templates/compressor/js_file.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/compressor/tests/static/js/three.js b/compressor/tests/static/js/three.js new file mode 100644 index 0000000..e01a825 --- /dev/null +++ b/compressor/tests/static/js/three.js @@ -0,0 +1 @@ +hermanos = {} \ No newline at end of file diff --git a/compressor/tests/static/js/two.js b/compressor/tests/static/js/two.js new file mode 100644 index 0000000..595f5b5 --- /dev/null +++ b/compressor/tests/static/js/two.js @@ -0,0 +1 @@ +pollos = {} \ No newline at end of file diff --git a/compressor/tests/test_base.py b/compressor/tests/test_base.py index d4de9d1..67dab7c 100644 --- a/compressor/tests/test_base.py +++ b/compressor/tests/test_base.py @@ -276,3 +276,31 @@ class CacheBackendTestCase(CompressorTestCase): def test_correct_backend(self): from compressor.cache import cache self.assertEqual(cache.__class__, locmem.LocMemCache) + + +class JsAsyncDeferTestCase(SimpleTestCase): + def setUp(self): + self.js = """\ + + + + + + + """ + + def test_js_output(self): + def extract_attr(tag): + if tag.has_attr('async'): + return 'async' + if tag.has_attr('defer'): + return 'defer' + js_node = JsCompressor(self.js) + output = [None, 'async', 'defer', None, 'async', None] + if six.PY3: + scripts = make_soup(js_node.output()).find_all('script') + attrs = [extract_attr(i) for i in scripts] + else: + scripts = make_soup(js_node.output()).findAll('script') + attrs = [s.get('async') or s.get('defer') for s in scripts] + self.assertEqual(output, attrs) diff --git a/compressor/tests/test_jinja2ext.py b/compressor/tests/test_jinja2ext.py index 5adc8ee..04adb9a 100644 --- a/compressor/tests/test_jinja2ext.py +++ b/compressor/tests/test_jinja2ext.py @@ -65,8 +65,7 @@ class TestJinja2CompressorExtension(TestCase): self.assertEqual(tag_body, template.render()) def test_empty_tag(self): - template = self.env.from_string("""{% compress js %}{% block js %} - {% endblock %}{% endcompress %}""") + template = self.env.from_string("""{% compress js %}{% block js %}{% endblock %}{% endcompress %}""") context = {'STATIC_URL': settings.COMPRESS_URL} self.assertEqual('', template.render(context))