Index: lib/ajax/ajaxlib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/ajax/ajaxlib.php,v retrieving revision 1.40.6.1 diff -u -r1.40.6.1 ajaxlib.php --- lib/ajax/ajaxlib.php 20 Nov 2007 14:24:41 -0000 1.40.6.1 +++ lib/ajax/ajaxlib.php 20 Nov 2007 17:10:42 -0000 @@ -3,64 +3,115 @@ * Library functions for using AJAX with Moodle. */ +define('REQUIREJS_BEFOREHEADER',0); +define('REQUIREJS_INHEADER',1); +define('REQUIREJS_AFTERHEADER',2); /** * Used to include JavaScript libraries. * - * When the $lib parameter is given, the function will add $lib to an - * internal list of libraries. When called without any parameters, it will - * return the html that is needed to load the JavaScript libraries in that - * list. Libraries that are included more than once will still only get loaded - * once, so this works like require_once() in PHP. + * When the $lib parameter is given, the function will ensure that the + * named library is loaded onto the page - either in the HTML
, + * just after the header, or at an arbitrary later point in the page, + * depending on where this function is called. * - * @param $lib - string or array of strings - * string(s) should be the shortname for the library or the - * full path to the library file. + * Libraries will not be included more than once, so this works like + * require_once in PHP. + * + * There are two special-case calls to this function: + * 1. Call with no value for $lib; this is used before printing the header. + * It returns the script tag code that should go inside the . + * 2. Call with $lib='' and $afterheader=true; this is used after printing + * the header and handles any require_js calls that occurred within the + * header itself. + * + * @param mixed $lib - string or array of strings + * string(s) should be the shortname for the library or the + * full path to the library file. + * @param bool $afterheader Should be set to true ONLY when being called at + * the end of the print_header function. * @return string or false or nothing. */ -function require_js($lib='') { +function require_js($lib='',$afterheader=false) { global $CFG; static $loadlibs = array(); + + static $state = REQUIREJS_BEFOREHEADER; + static $latecode = ''; if (!ajaxenabled()) { //return false; } - + if (!empty($lib)) { // Add the lib to the list of libs to be loaded, if it isn't already // in the list. if (is_array($lib)) { - array_map('require_js', $lib); + foreach($lib as $singlelib) { + require_js($singlelib); + } } else { $libpath = ajax_get_lib($lib); if (array_search($libpath, $loadlibs) === false) { $loadlibs[] = $libpath; - // If this is called after header, then we print it right away - // as otherwise nothing will ever happen! - if (defined('HEADER_PRINTED')) { - $realloadlibs=$loadlibs; - $loadlibs=array($libpath); - print require_js(); - $loadlibs=$realloadlibs; + + // For state other than 0 we need to take action as well as just + // adding it to loadlibs + if($state != REQUIREJS_BEFOREHEADER) { + // Get the script statement for this library + $scriptstatement=get_require_js_code(array($libpath)); + + if($state == REQUIREJS_AFTERHEADER) { + // After the header, print it immediately + print $scriptstatement; + } else { + // Haven't finished the header yet. Add it after the + // header + $latecode .= $scriptstatement; + } } } } + } else if($afterheader) { + if($state !== REQUIREJS_INHEADER) { + debugging('Incorrect state in require_js (expected INHEADER): be careful not to call with empty $lib (except in print_header)'); + return ''; + } else { + $state = REQUIREJS_AFTERHEADER; + return $latecode; + } } else { - // Return the html needed to load the JavaScript files defined in - // our list of libs to be loaded. - $output = ''; - - foreach ($loadlibs as $loadlib) { - $output .= '\n"; - if ($loadlib == $CFG->wwwroot.'/lib/yui/logger/logger-min.js') { - // Special case, we need the CSS too. - $output .= 'wwwroot}/lib/yui/logger/assets/logger.css\" />\n"; - } + if($state !== REQUIREJS_BEFOREHEADER) { + debugging('Incorrect state in require_js (expected BEFOREHEADER): be careful not to call with empty $lib (except in print_header)'); + } else { + $state = REQUIREJS_INHEADER; + } + + return get_require_js_code($loadlibs); + } +} + +/** + * Should not be called directly - use require_js. This function obtains the code + * (script tags) needed to include JavaScript libraries. + * @param array $loadlibs Array of library files to include + * @return string HTML code to include them + */ +function get_require_js_code($loadlibs) { + global $CFG; + // Return the html needed to load the JavaScript files defined in + // our list of libs to be loaded. + $output = ''; + foreach ($loadlibs as $loadlib) { + $output .= '\n"; + if ($loadlib == $CFG->wwwroot.'/lib/yui/logger/logger-min.js') { + // Special case, we need the CSS too. + $output .= 'wwwroot}/lib/yui/logger/assets/logger.css\" />\n"; } - return $output; } + return $output; } Index: lib/weblib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/weblib.php,v retrieving revision 1.970.2.19 diff -u -r1.970.2.19 weblib.php --- lib/weblib.php 19 Nov 2007 01:42:38 -0000 1.970.2.19 +++ lib/weblib.php 20 Nov 2007 17:10:42 -0000 @@ -2524,6 +2524,9 @@ $output .= message_popup_window(); } + // Add in any extra JavaScript libraries that occurred during the header + $output .= require_js('', true); + if ($return) { return $output; } else {