Browse Source

Fixed #33446 -- Added CSS source map support to ManifestStaticFilesStorage.

Adam Johnson 3 years ago
parent
commit
dc8bb35e39

+ 4 - 0
django/contrib/staticfiles/storage.py

@@ -51,6 +51,10 @@ class HashedFilesMixin:
                 r"""(?P<matched>@import\s*["']\s*(?P<url>.*?)["'])""",
                 """@import url("%(url)s")""",
             ),
+            (
+                r'(?m)(?P<matched>)^(/\*# (?-i:sourceMappingURL)=(?P<url>.*) \*/)$',
+                '/*# sourceMappingURL=%(url)s */',
+            ),
         )),
         ('*.js', (
             (

+ 6 - 2
docs/ref/contrib/staticfiles.txt

@@ -294,7 +294,7 @@ method). The regular expressions used to find those paths
 (``django.contrib.staticfiles.storage.HashedFilesMixin.patterns``) cover:
 
 * The `@import`_ rule and `url()`_ statement of `Cascading Style Sheets`_.
-* The `source map`_ comment in JavaScript.
+* `Source map`_ comments in CSS and JavaScript files.
 
 For example, the ``'css/styles.css'`` file with this content:
 
@@ -327,10 +327,14 @@ argument. For example::
 
 .. versionchanged:: 4.0
 
-    Support for finding paths in the source map comments was added.
+    Support for finding paths in JavaScript source map comments was added.
 
     The ``manifest_storage`` argument was added.
 
+.. versionchanged:: 4.1
+
+    Support for finding paths in CSS source map comments was added.
+
 .. attribute:: storage.ManifestStaticFilesStorage.max_post_process_passes
 
 Since static files might reference other static files that need to have their

+ 2 - 1
docs/releases/4.1.txt

@@ -139,7 +139,8 @@ Minor features
 :mod:`django.contrib.staticfiles`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-* ...
+* :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
+  replaces paths to CSS source map references with their hashed counterparts.
 
 :mod:`django.contrib.syndication`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 2 - 0
tests/staticfiles_tests/project/documents/cached/source_map.css

@@ -0,0 +1,2 @@
+* {outline: 1px solid red;}
+/*# sourceMappingURL=source_map.css.map */

+ 1 - 0
tests/staticfiles_tests/project/documents/cached/source_map.css.map

@@ -0,0 +1 @@
+{}

+ 2 - 0
tests/staticfiles_tests/project/documents/cached/source_map_sensitive.css

@@ -0,0 +1,2 @@
+* {outline: 1px solid red;}
+/*# sOuRcEMaPpInGURL=source_map.css.map */

+ 24 - 0
tests/staticfiles_tests/test_storage.py

@@ -212,6 +212,30 @@ class TestHashedFiles:
             self.assertIn(b"other.d41d8cd98f00.css", content)
         self.assertPostCondition()
 
+    def test_css_source_map(self):
+        relpath = self.hashed_file_path('cached/source_map.css')
+        self.assertEqual(relpath, 'cached/source_map.b2fceaf426aa.css')
+        with storage.staticfiles_storage.open(relpath) as relfile:
+            content = relfile.read()
+            self.assertNotIn(b'/*# sourceMappingURL=source_map.css.map */', content)
+            self.assertIn(
+                b'/*# sourceMappingURL=source_map.css.99914b932bd3.map */',
+                content,
+            )
+        self.assertPostCondition()
+
+    def test_css_source_map_sensitive(self):
+        relpath = self.hashed_file_path('cached/source_map_sensitive.css')
+        self.assertEqual(relpath, 'cached/source_map_sensitive.456683f2106f.css')
+        with storage.staticfiles_storage.open(relpath) as relfile:
+            content = relfile.read()
+            self.assertIn(b'/*# sOuRcEMaPpInGURL=source_map.css.map */', content)
+            self.assertNotIn(
+                b'/*# sourceMappingURL=source_map.css.99914b932bd3.map */',
+                content,
+            )
+        self.assertPostCondition()
+
     def test_js_source_map(self):
         relpath = self.hashed_file_path('cached/source_map.js')
         self.assertEqual(relpath, 'cached/source_map.cd45b8534a87.js')