diff --git django/contrib/staticfiles/storage.py django/contrib/staticfiles/storage.py
index b3ee32e665..9f5077edad 100644
|
|
|
def url(self, name, force=False):
|
| 194 | 194 | """ |
| 195 | 195 | return self._url(self.stored_name, name, force) |
| 196 | 196 | |
| 197 | | def url_converter(self, name, hashed_files, template=None): |
| | 197 | def url_converter(self, name, hashed_files, template, commented_regions): |
| 198 | 198 | """ |
| 199 | 199 | Return the custom URL converter for the given file name. |
| 200 | 200 | """ |
| … |
… |
def converter(matchobj):
|
| 212 | 212 | matched = matches["matched"] |
| 213 | 213 | url = matches["url"] |
| 214 | 214 | |
| | 215 | from bisect import bisect |
| | 216 | |
| | 217 | if len(commented_regions): |
| | 218 | m_start, m_end = span = matchobj.span() |
| | 219 | comment_index = bisect(commented_regions, span) |
| | 220 | if comment_index != 0: |
| | 221 | c_start, c_end = commented_regions[comment_index - 1] |
| | 222 | # If match lies within commented region |
| | 223 | if c_start <= m_start and m_end <= c_end: |
| | 224 | return matched |
| | 225 | |
| 215 | 226 | # Ignore absolute/protocol-relative and data-uri URLs. |
| 216 | 227 | if re.match(r"^[a-z]+:", url): |
| 217 | 228 | return matched |
| … |
… |
def path_level(name):
|
| 356 | 367 | content = original_file.read().decode("utf-8") |
| 357 | 368 | for extension, patterns in self._patterns.items(): |
| 358 | 369 | if matches_patterns(path, (extension,)): |
| | 370 | commented_regions = self._parse_commented_regions( |
| | 371 | extension, content |
| | 372 | ) |
| 359 | 373 | for pattern, template in patterns: |
| 360 | 374 | converter = self.url_converter( |
| 361 | | name, hashed_files, template |
| | 375 | name, hashed_files, template, commented_regions |
| 362 | 376 | ) |
| 363 | 377 | try: |
| 364 | 378 | content = pattern.sub(converter, content) |
| … |
… |
def path_level(name):
|
| 396 | 410 | |
| 397 | 411 | yield name, hashed_name, processed, substitutions |
| 398 | 412 | |
| | 413 | def _parse_commented_regions(self, extension, content): |
| | 414 | if extension == "*.js": |
| | 415 | js_region_re = re.compile( |
| | 416 | r""" |
| | 417 | ( |
| | 418 | # single-quoted strings |
| | 419 | '([^'\\]|(\\.))*?' |
| | 420 | # double-quoted strings |
| | 421 | |"([^"\\]|(\\.))*?" |
| | 422 | # template literals |
| | 423 | |`.*?` |
| | 424 | # single line comments |
| | 425 | |//.*?\n |
| | 426 | # multi-line comments |
| | 427 | |/\*.*?\*/ |
| | 428 | ) |
| | 429 | """, |
| | 430 | re.VERBOSE | re.DOTALL, |
| | 431 | ) |
| | 432 | return [m.span() for m in js_region_re.finditer(content)] |
| | 433 | else: |
| | 434 | return [] |
| | 435 | |
| 399 | 436 | def clean_name(self, name): |
| 400 | 437 | return name.replace("\\", "/") |
| 401 | 438 | |