Skip to content

Fix static #2534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 57 additions & 27 deletions custom_storages/storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ class PipelineManifestStorage(PipelineMixin, ManifestFilesMixin, StaticFilesStor
imports in comments. Ref: https://code.djangoproject.com/ticket/21080
"""

# Skip map files
# https://code.djangoproject.com/ticket/33353#comment:13
patterns = (
(
"*.css",
(
"(?P<matched>url\\(['\"]{0,1}\\s*(?P<url>.*?)[\"']{0,1}\\))",
(
"(?P<matched>@import\\s*[\"']\\s*(?P<url>.*?)[\"'])",
'@import url("%(url)s")',
),
),
),
)

def get_comment_blocks(self, content):
"""
Return a list of (start, end) tuples for each comment block.
Expand All @@ -32,73 +47,85 @@ def get_comment_blocks(self, content):
for match in re.finditer(r'\/\*.*?\*\/', content, flags=re.DOTALL)
]

def url_converter(self, name, hashed_files, template=None, comment_blocks=None):

def is_in_comment(self, pos, comments):
for start, end in comments:
if start < pos and pos < end:
return True
if pos < start:
return False
return False


def url_converter(self, name, hashed_files, template=None, comment_blocks=[]):
"""
Return the custom URL converter for the given file name.
"""
if comment_blocks is None:
comment_blocks = []

if template is None:
template = self.default_template

def converter(matchobj):
"""
Convert the matched URL to a normalized and hashed URL.

This requires figuring out which files the matched URL resolves
to and calling the url() method of the storage.
"""
matched, url = matchobj.groups()
matches = matchobj.groupdict()
matched = matches["matched"]
url = matches["url"]

# Ignore URLs in comments.
if self.is_in_comment(matchobj.start(), comment_blocks):
return matched

# Ignore absolute/protocol-relative and data-uri URLs.
if re.match(r'^[a-z]+:', url):
if re.match(r"^[a-z]+:", url):
return matched

# Ignore absolute URLs that don't point to a static file (dynamic
# CSS / JS?). Note that STATIC_URL cannot be empty.
if url.startswith('/') and not url.startswith(settings.STATIC_URL):
if url.startswith("/") and not url.startswith(settings.STATIC_URL):
return matched

# Strip off the fragment so a path-like fragment won't interfere.
url_path, fragment = urldefrag(url)

if url_path.startswith('/'):
# Ignore URLs without a path
if not url_path:
return matched

if url_path.startswith("/"):
# Otherwise the condition above would have returned prematurely.
assert url_path.startswith(settings.STATIC_URL)
target_name = url_path[len(settings.STATIC_URL):]
target_name = url_path[len(settings.STATIC_URL) :]
else:
# We're using the posixpath module to mix paths and URLs conveniently.
source_name = name if os.sep == '/' else name.replace(os.sep, '/')
source_name = name if os.sep == "/" else name.replace(os.sep, "/")
target_name = posixpath.join(posixpath.dirname(source_name), url_path)

# Determine the hashed name of the target file with the storage backend.
hashed_url = self._url(
self._stored_name, unquote(target_name),
force=True, hashed_files=hashed_files,
self._stored_name,
unquote(target_name),
force=True,
hashed_files=hashed_files,
)

transformed_url = '/'.join(url_path.split('/')[:-1] + hashed_url.split('/')[-1:])
transformed_url = "/".join(
url_path.split("/")[:-1] + hashed_url.split("/")[-1:]
)

# Restore the fragment that was stripped off earlier.
if fragment:
transformed_url += ('?#' if '?#' in url else '#') + fragment
transformed_url += ("?#" if "?#" in url else "#") + fragment

# Return the hashed version to the file
return template % unquote(transformed_url)
matches["url"] = unquote(transformed_url)
return template % matches

return converter

def is_in_comment(self, pos, comments):
for start, end in comments:
if start < pos and pos < end:
return True
if pos < start:
return False
return False

def _post_process(self, paths, adjustable_paths, hashed_files):
# Sort the files by directory level
Expand All @@ -122,7 +149,7 @@ def path_level(name):
hashed_name = hashed_files[hash_key]

# then get the original's file content..
if hasattr(original_file, 'seek'):
if hasattr(original_file, "seek"):
original_file.seek(0)

hashed_file_exists = self.exists(hashed_name)
Expand All @@ -131,12 +158,14 @@ def path_level(name):
# ..to apply each replacement pattern to the content
if name in adjustable_paths:
old_hashed_name = hashed_name
content = original_file.read().decode(settings.FILE_CHARSET)
content = original_file.read().decode("utf-8")
for extension, patterns in self._patterns.items():
if matches_patterns(path, (extension,)):
comment_blocks = self.get_comment_blocks(content)
for pattern, template in patterns:
converter = self.url_converter(name, hashed_files, template, comment_blocks)
converter = self.url_converter(
name, hashed_files, template, comment_blocks
)
try:
content = pattern.sub(converter, content)
except ValueError as exc:
Expand All @@ -145,8 +174,9 @@ def path_level(name):
self.delete(hashed_name)
# then save the processed result
content_file = ContentFile(content.encode())
# Save intermediate file for reference
saved_name = self._save(hashed_name, content_file)
if self.keep_intermediate_files:
# Save intermediate file for reference
self._save(hashed_name, content_file)
hashed_name = self.hashed_name(name, content_file)

if self.exists(hashed_name):
Expand Down
3 changes: 2 additions & 1 deletion static/js/plugins/IE7.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Unknown W Brackets, Benjamin Westfarer, Rob Eberhardt,
Bill Edney, Kevin Newman, James Crompton, Matthew Mastracci,
Doug Wright, Richard York, Kenneth Kolano, MegaZone,
Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer �hlfors,
Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer Åhlfors,
David Zulaica, Ken Kolano, Kevin Newman, Sjoerd Visscher,
Ingo Chao
*/
Expand Down Expand Up @@ -2406,3 +2406,4 @@ IE7.loaded = true;
})();

})(this, document);

2 changes: 1 addition & 1 deletion static/js/plugins/IE9.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Unknown W Brackets, Benjamin Westfarer, Rob Eberhardt,
Bill Edney, Kevin Newman, James Crompton, Matthew Mastracci,
Doug Wright, Richard York, Kenneth Kolano, MegaZone,
Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer �hlfors,
Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer Åhlfors,
David Zulaica, Ken Kolano, Kevin Newman, Sjoerd Visscher,
Ingo Chao
*/
Expand Down