You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.7 KiB
69 lines
2.7 KiB
from compressor.conf import settings
|
|
from compressor.base import Compressor, SOURCE_HUNK, SOURCE_FILE
|
|
|
|
|
|
class JsCompressor(Compressor):
|
|
|
|
output_mimetypes = {"text/javascript"}
|
|
|
|
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)
|
|
else:
|
|
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.copy(content=self.parser.elem_str(elem))
|
|
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, "extra_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().output(*args, **kwargs)
|
|
|
|
def filter_input(self, forced=False):
|
|
"""
|
|
Passes each hunk (file or code) to the 'input' methods
|
|
of the compressor filters.
|
|
"""
|
|
content = []
|
|
for hunk in self.hunks(forced):
|
|
# If a file ends with a function call, say, console.log()
|
|
# but doesn't have a semicolon, and the next file starts with
|
|
# a (, the individual files are ok, but when combined you get an
|
|
# error like TypeError...
|
|
# Forcing a semicolon in between fixes it.
|
|
if settings.COMPRESS_ENABLED or forced:
|
|
hunk += ";"
|
|
content.append(hunk)
|
|
return content
|