mirror of
https://github.com/moodle/moodle.git
synced 2025-04-16 05:54:19 +02:00
MDL-78157 js: Be more careful about inserting missing module names
It is perfectly legitimate to create and/or use a method named `define` in JS outside of RequireJS. Unfortunately our requirejs.php wrapper is dumb and does not understand this. In the long term we need to stop doing this at all. We really should be able to already, but every time I try to something prevents it. In the interim, this change adds a secondary check to see if there is an existing define which _does_ have the right name in it already.
This commit is contained in:
parent
2e1c6fd43e
commit
9b174fd3cc
@ -52,6 +52,43 @@ $file = '/' . min_clean_param($file, 'SAFEPATH');
|
||||
$jsfiles = array();
|
||||
list($unused, $component, $module) = explode('/', $file, 3);
|
||||
|
||||
/**
|
||||
* Helper function to fix missing module names in JavaScript.
|
||||
*
|
||||
* TODO Remove this function when we find a reliable way to do this in the Grunt task.
|
||||
* @param string $modulename
|
||||
* @param string $js
|
||||
* @return string The modified JavaScript.
|
||||
*/
|
||||
function requirejs_fix_define(string $modulename, string $js): string {
|
||||
// First check whether there is a possible missing module name. That is:
|
||||
// define (function(Foo) {
|
||||
// instead of:
|
||||
// define('mod_foo/bar', function(Foo) {
|
||||
$missingmodule = preg_match('/define\(\s*(\[|function)/', $js);
|
||||
|
||||
// Now check whether the module name is already defined elsewhere.
|
||||
// This could be a totally unrelated use of the word define.
|
||||
// Note: This code needs to die, in a fire. It is evil and wrong.
|
||||
$missingmodule = $missingmodule && !preg_match("@define\s*\(\s*['\"]{$modulename}['\"]@", $js);
|
||||
|
||||
if ($missingmodule) {
|
||||
// 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.
|
||||
return implode($replace, explode('define(', $js, 2));
|
||||
} else if (!preg_match('/define\s*\(/', $js)) {
|
||||
echo(
|
||||
"// JS module '{$modulename}' cannot be loaded, or does not contain a javascript" .
|
||||
' module in AMD format. "define()" not found.'
|
||||
);
|
||||
}
|
||||
|
||||
return $js;
|
||||
}
|
||||
|
||||
// Use the caching only for meaningful revision numbers which prevents future cache poisoning.
|
||||
if ($rev > 0 and $rev < (time() + 60 * 60)) {
|
||||
// This is "production mode".
|
||||
@ -104,14 +141,7 @@ if ($rev > 0 and $rev < (time() + 60 * 60)) {
|
||||
$js = rtrim($js);
|
||||
$js .= "\n";
|
||||
|
||||
if (preg_match('/define\(\s*(\[|function)/', $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));
|
||||
}
|
||||
$js = requirejs_fix_define($modulename, $js);
|
||||
|
||||
$content .= $js;
|
||||
}
|
||||
@ -157,17 +187,7 @@ if (!empty($jsfiles)) {
|
||||
$js = rtrim($js);
|
||||
}
|
||||
|
||||
if (preg_match('/define\(\s*(\[|function)/', $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);
|
||||
}
|
||||
$js = requirejs_fix_define($modulename, $js);
|
||||
|
||||
js_send_uncached($js, 'requirejs.php');
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user