MDL-62497 javascript: add babel transpiling to Grunt for ES6 support
[moodle.git] / lib / requirejs.php
index f6140a4..96b4cfc 100644 (file)
@@ -104,12 +104,20 @@ if ($rev > 0 and $rev < (time() + 60 * 60)) {
                 $content = $js . $content;
                 continue;
             }
+            // Remove source map link.
+            $js = preg_replace('~//# sourceMappingURL.*$~s', '', $js);
+            $js = rtrim($js);
             $js .= "\n";
-            // Inject the module name into the define.
-            $replace = 'define(\'' . $modulename . '\', ';
-            $search = 'define(';
-            // Replace only the first occurrence.
-            $js = implode($replace, explode($search, $js, 2));
+
+            if (preg_match('/define\(\s*\[/', $js)) {
+                // If the JavaScript module has been defined without specifying a name then we'll
+                // add the Moodle module name now.
+                $replace = 'define(\'' . $modulename . '\', ';
+                $search = 'define(';
+                // Replace only the first occurrence.
+                $js = implode($replace, explode($search, $js, 2));
+            }
+
             $content .= $js;
         }
 
@@ -123,29 +131,65 @@ if ($rev > 0 and $rev < (time() + 60 * 60)) {
     }
 }
 
+// Ok, now we need to start normal moodle because we need access to the autoloader.
+define('ABORT_AFTER_CONFIG_CANCEL', true);
+// Session not used here.
+define('NO_MOODLE_COOKIES', true);
+// Ignore upgrade check.
+define('NO_UPGRADE_CHECK', true);
+
+require("$CFG->dirroot/lib/setup.php");
+
 if ($lazyload) {
-    $jsfiles = core_requirejs::find_one_amd_module($component, $module, true);
+    $jsfiles = core_requirejs::find_one_amd_module($component, $module, false);
 } else {
-    $jsfiles = core_requirejs::find_all_amd_modules(true);
+    $jsfiles = core_requirejs::find_all_amd_modules(false);
 }
 
-$content = '';
+// The content of the resulting file.
+$result = [];
+// Sort the files to ensure consistent ordering for source map generation.
+asort($jsfiles);
+
 foreach ($jsfiles as $modulename => $jsfile) {
     $shortfilename = str_replace($CFG->dirroot, '', $jsfile);
-    $js = "// ---- $shortfilename ----\n";
-    $js .= file_get_contents($jsfile) . "\n";
-    // Inject the module name into the define.
-    $replace = 'define(\'' . $modulename . '\', ';
-    $search = 'define(';
-
-    if (strpos($js, $search) === false) {
-        // We can't call debugging because we only have minimal config loaded.
-        header('HTTP/1.0 500 error');
-        die('JS file: ' . $shortfilename . ' cannot be loaded, or does not contain a javascript module in AMD format. "define()" not found.');
+    $mapfile = $jsfile . '.map';
+
+    if (file_exists($mapfile)) {
+        // We've got a a source map file so we can return the minified file here and
+        // the source map will be used by the browser to debug.
+        $js = file_get_contents($jsfile);
+        // Remove source map link from the individual file because we add back a single
+        // source map link to the whole file at the end.
+        $js = preg_replace('~//# sourceMappingURL.*$~s', '', $js);
+    } else {
+        // This file doesn't have a map file. We might be dealing with an older source file from
+        // a plugin or previous version of Moodle so we should just return the full original source
+        // like we used to.
+        $originalsource = str_replace('/amd/build/', '/amd/src/', $jsfile);
+        $originalsource = str_replace('.min.js', '.js', $originalsource);
+        $js = file_get_contents($originalsource);
     }
 
-    // Replace only the first occurrence.
-    $js = implode($replace, explode($search, $js, 2));
-    $content .= $js;
+    $js = rtrim($js);
+
+    if (preg_match('/define\(\s*\[/', $js)) {
+        // If the JavaScript module has been defined without specifying a name then we'll
+        // add the Moodle module name now.
+        $replace = 'define(\'' . $modulename . '\', ';
+
+        // Replace only the first occurrence.
+        $js = implode($replace, explode('define(', $js, 2));
+    } else if (!preg_match('/define\s*\(/', $js)) {
+        debugging('JS file: ' . $shortfilename . ' cannot be loaded, or does not contain a javascript' .
+                  ' module in AMD format. "define()" not found.', DEBUG_DEVELOPER);
+    }
+
+    $result[] = $js;
 }
+
+$mapdataurl = '//# sourceMappingURL=' . (new \moodle_url('/lib/jssourcemap.php/' . $slashargument))->out();
+$result[] = $mapdataurl;
+$content = implode("\n", $result);
+
 js_send_uncached($content, 'requirejs.php');