From e13963221890fa3e8266633a845cc4c03d7a90ad Mon Sep 17 00:00:00 2001
From: webchick <drupal@webchick.net>
Date: Sat, 18 Apr 2015 07:06:10 -0700
Subject: [PATCH] Issue #2400287 by hass, cutesquirrel, borisson_, rteijeiro,
 pfrenssen, cilefen: Remove all occurences of sourceMappingURL and sourceURL
 when JS files are aggregated

---
 .../Core/Asset/AssetOptimizerInterface.php    | 11 +++
 core/lib/Drupal/Core/Asset/CssOptimizer.php   | 23 ++++-
 .../Core/Asset/JsCollectionOptimizer.php      |  2 +
 core/lib/Drupal/Core/Asset/JsOptimizer.php    | 16 ++++
 .../Tests/Core/Asset/JsOptimizerUnitTest.php  | 83 +++++++++++++++++++
 .../Asset/css_test_files/charset_newline.css  |  2 +-
 .../charset_sameline.css.optimized.css        |  1 -
 .../js_test_files/source_mapping_url.min.js   |  2 +
 .../source_mapping_url.min.js.optimized.js    |  1 +
 .../source_mapping_url_old.min.js             |  2 +
 ...source_mapping_url_old.min.js.optimized.js |  1 +
 .../Asset/js_test_files/source_url.min.js     |  2 +
 .../source_url.min.js.optimized.js            |  1 +
 .../Asset/js_test_files/source_url_old.min.js |  2 +
 .../source_url_old.min.js.optimized.js        |  1 +
 15 files changed, 146 insertions(+), 4 deletions(-)
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
 delete mode 100644 core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_sameline.css.optimized.css
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js.optimized.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js.optimized.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js.optimized.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js.optimized.js

diff --git a/core/lib/Drupal/Core/Asset/AssetOptimizerInterface.php b/core/lib/Drupal/Core/Asset/AssetOptimizerInterface.php
index 31c4b9371b3b..171583dc9f73 100644
--- a/core/lib/Drupal/Core/Asset/AssetOptimizerInterface.php
+++ b/core/lib/Drupal/Core/Asset/AssetOptimizerInterface.php
@@ -22,4 +22,15 @@ interface AssetOptimizerInterface {
    */
   public function optimize(array $asset);
 
+  /**
+   * Removes unwanted content from an asset.
+   *
+   * @param string $content
+   *   The content of an asset.
+   *
+   * @return string
+   *   The cleaned asset's contents.
+   */
+  public function clean($content);
+
 }
diff --git a/core/lib/Drupal/Core/Asset/CssOptimizer.php b/core/lib/Drupal/Core/Asset/CssOptimizer.php
index b93a638f9e41..673012b87f46 100644
--- a/core/lib/Drupal/Core/Asset/CssOptimizer.php
+++ b/core/lib/Drupal/Core/Asset/CssOptimizer.php
@@ -39,12 +39,31 @@ public function optimize(array $css_asset) {
     }
   }
 
+  /**
+   * Processes the contents of a CSS asset for cleanup.
+   *
+   * @param string $contents
+   *   The contents of the CSS asset.
+   *
+   * @return string
+   *   Contents of the CSS asset.
+   */
+  public function clean($contents) {
+    // Remove multiple charset declarations for standards compliance (and fixing
+    // Safari problems).
+    $contents = preg_replace('/^@charset\s+[\'"](\S*?)\b[\'"];/i', '', $contents);
+
+    return $contents;
+  }
+
   /**
    * Build aggregate CSS file.
    */
   protected function processFile($css_asset) {
     $contents = $this->loadFile($css_asset['data'], TRUE);
 
+    $contents = $this->clean($contents);
+
     // Get the parent directory of this file, relative to the Drupal root.
     $css_base_path = substr($css_asset['data'], 0, strrpos($css_asset['data'], '/'));
     // Store base path.
@@ -161,8 +180,8 @@ protected function loadNestedFile($matches) {
    *   Contents of the stylesheet including the imported stylesheets.
    */
   protected function processCss($contents, $optimize = FALSE) {
-    // Remove multiple charset declarations for standards compliance (and fixing Safari problems).
-    $contents = preg_replace('/^@charset\s+[\'"](\S*?)\b[\'"];/i', '', $contents);
+    // Remove unwanted CSS code that cause issues.
+    $contents = $this->clean($contents);
 
     if ($optimize) {
       // Perform some safe CSS optimizations.
diff --git a/core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php b/core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php
index 68626ec4208a..a21725dedb99 100644
--- a/core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php
+++ b/core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php
@@ -123,6 +123,8 @@ public function optimize(array $js_assets) {
                 // from running together.
                 $data .= ";\n";
               }
+              // Remove unwanted JS code that cause issues.
+              $data = $this->optimizer->clean($data);
               // Dump the optimized JS for this group into an aggregate file.
               $uri = $this->dumper->dump($data, 'js');
               // Set the URI for this group's aggregate file.
diff --git a/core/lib/Drupal/Core/Asset/JsOptimizer.php b/core/lib/Drupal/Core/Asset/JsOptimizer.php
index e6ad2939e481..bd004a512a3d 100644
--- a/core/lib/Drupal/Core/Asset/JsOptimizer.php
+++ b/core/lib/Drupal/Core/Asset/JsOptimizer.php
@@ -28,4 +28,20 @@ public function optimize(array $js_asset) {
     return file_get_contents($js_asset['data']);
   }
 
+  /**
+   * Processes the contents of a javascript asset for cleanup.
+   *
+   * @param string $contents
+   *   The contents of the javascript asset.
+   *
+   * @return string
+   *   Contents of the javascript asset.
+   */
+  public function clean($contents) {
+    // Remove JS source and source mapping urls or these may cause 404 errors.
+    $contents = preg_replace('/\/\/(#|@)\s(sourceURL|sourceMappingURL)=\s*(\S*?)\s*$/m', '', $contents);
+
+    return $contents;
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
new file mode 100644
index 000000000000..13bd77cbbc68
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Asset\JsOptimizerUnitTest.
+ */
+
+namespace Drupal\Tests\Core\Asset;
+
+use Drupal\Core\Asset\JsOptimizer;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the JS asset optimizer.
+ *
+ * @group Asset
+ */
+class JsOptimizerUnitTest extends UnitTestCase {
+
+  /**
+   * A JS asset optimizer.
+   *
+   * @var \Drupal\Core\Asset\JsOptimizer object.
+   */
+  protected $optimizer;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->optimizer = new JsOptimizer();
+  }
+
+  /**
+   * Provides data for the JS asset cleaning test.
+   *
+   * @see \Drupal\Core\Asset\JsOptimizer::clean().
+   *
+   * @returns array
+   *   An array of test data.
+   */
+  function providerTestClean() {
+    $path = dirname(__FILE__)  . '/js_test_files/';
+    return array(
+      // File. Tests:
+      // - Stripped sourceMappingURL with comment # syntax.
+      0 => array(
+        file_get_contents($path . 'source_mapping_url.min.js'),
+        file_get_contents($path . 'source_mapping_url.min.js.optimized.js'),
+      ),
+      // File. Tests:
+      // - Stripped sourceMappingURL with comment @ syntax.
+      1 => array(
+        file_get_contents($path . 'source_mapping_url_old.min.js'),
+        file_get_contents($path . 'source_mapping_url_old.min.js.optimized.js'),
+      ),
+      // File. Tests:
+      // - Stripped sourceURL with comment # syntax.
+      2 => array(
+        file_get_contents($path . 'source_url.min.js'),
+        file_get_contents($path . 'source_url.min.js.optimized.js'),
+      ),
+      // File. Tests:
+      // - Stripped sourceURL with comment @ syntax.
+      3 => array(
+        file_get_contents($path . 'source_url_old.min.js'),
+        file_get_contents($path . 'source_url_old.min.js.optimized.js'),
+      ),
+    );
+  }
+
+  /**
+   * Tests cleaning of a JS asset group containing 'type' => 'file'.
+   *
+   * @dataProvider providerTestClean
+   */
+  function testClean($js_asset, $expected) {
+    $this->assertEquals($expected, $this->optimizer->clean($js_asset));
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_newline.css b/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_newline.css
index 68f3f42b2cfa..21aacf2dcd67 100644
--- a/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_newline.css
+++ b/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_newline.css
@@ -1,2 +1,2 @@
-@charset 'UTF-8';
+@charset "UTF-8";
 html{font-family:"sans-serif";}
diff --git a/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_sameline.css.optimized.css b/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_sameline.css.optimized.css
deleted file mode 100644
index c9e6aded3cd9..000000000000
--- a/core/tests/Drupal/Tests/Core/Asset/css_test_files/charset_sameline.css.optimized.css
+++ /dev/null
@@ -1 +0,0 @@
-html{font-family:"sans-serif";}
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js
new file mode 100644
index 000000000000..4e133bdbe29e
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js
@@ -0,0 +1,2 @@
+(function($) { "use strict"; })
+//# sourceMappingURL=source_mapping_url.min.map
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js.optimized.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js.optimized.js
new file mode 100644
index 000000000000..ec09066aa14a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url.min.js.optimized.js
@@ -0,0 +1 @@
+(function($) { "use strict"; })
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js
new file mode 100644
index 000000000000..b937b8691a90
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js
@@ -0,0 +1,2 @@
+(function($) { "use strict"; })
+//@ sourceMappingURL=source_mapping_url.min.map
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js.optimized.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js.optimized.js
new file mode 100644
index 000000000000..ec09066aa14a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_mapping_url_old.min.js.optimized.js
@@ -0,0 +1 @@
+(function($) { "use strict"; })
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js
new file mode 100644
index 000000000000..efb203286526
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js
@@ -0,0 +1,2 @@
+(function($) { "use strict"; })
+//# sourceURL=source_mapping_url.js
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js.optimized.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js.optimized.js
new file mode 100644
index 000000000000..ec09066aa14a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url.min.js.optimized.js
@@ -0,0 +1 @@
+(function($) { "use strict"; })
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js
new file mode 100644
index 000000000000..dd26bd587390
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js
@@ -0,0 +1,2 @@
+(function($) { "use strict"; })
+//@ sourceURL=source_mapping_url.js
diff --git a/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js.optimized.js b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js.optimized.js
new file mode 100644
index 000000000000..ec09066aa14a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/js_test_files/source_url_old.min.js.optimized.js
@@ -0,0 +1 @@
+(function($) { "use strict"; })
-- 
GitLab