From ca70075a39263d6fc887dbfb56669ceb378a19ff Mon Sep 17 00:00:00 2001 From: sam_marshall Date: Tue, 20 Nov 2007 18:04:03 +0000 Subject: [PATCH] MDL-12284 Moved require_js to weblib and improved it so that it works if called during header (also tidied up code) --- lib/ajax/ajaxlib.php | 61 ---------------------- lib/weblib.php | 119 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 66 deletions(-) diff --git a/lib/ajax/ajaxlib.php b/lib/ajax/ajaxlib.php index 8d2f1874b2d06..ec953df4f13df 100644 --- a/lib/ajax/ajaxlib.php +++ b/lib/ajax/ajaxlib.php @@ -3,67 +3,6 @@ * Library functions for using AJAX with Moodle. */ - -/** - * 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. - * - * @param $lib - string or array of strings - * string(s) should be the shortname for the library or the - * full path to the library file. - * @return string or false or nothing. - */ -function require_js($lib='') { - global $CFG; - static $loadlibs = array(); - - 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); - } 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; - } - } - } - } 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"; - } - } - return $output; - } -} - - /** * Get the path to a JavaScript library. * @param $libname - the name of the library whose path we need. diff --git a/lib/weblib.php b/lib/weblib.php index abb3484003de2..826fda7f44ccb 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -2348,11 +2348,7 @@ function print_header ($title='', $heading='', $navigation='', $focus='', $meta = $meta."\n".$metapage; - -/// Add the required JavaScript Libraries for AJAX -// if (!empty($CFG->enableajax)) { // This is the way all JS should be included, so get rid of the test. - $meta .= "\n".require_js(); -// } + $meta .= "\n".require_js('',1); /// Set up some navigation variables @@ -2524,6 +2520,9 @@ function print_header ($title='', $heading='', $navigation='', $focus='', $output .= message_popup_window(); } + // Add in any extra JavaScript libraries that occurred during the header + $output .= require_js('', 2); + if ($return) { return $output; } else { @@ -2531,6 +2530,116 @@ function print_header ($title='', $heading='', $navigation='', $focus='', } } +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 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. + * + * 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 which are both used only + * by weblib print_header: + * $extracthtml = 1: this is used before printing the header. + * It returns the script tag code that should go inside the . + * $extracthtml = 2: 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 int $extracthtml Do not set this parameter usually (leave 0), only + * weblib should set this to 1 or 2 in print_header function. + * @return mixed No return value, except when using $extracthtml it returns the html code. + */ +function require_js($lib,$extracthtml=0) { + global $CFG; + static $loadlibs = array(); + + static $state = REQUIREJS_BEFOREHEADER; + static $latecode = ''; + + 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)) { + foreach($lib as $singlelib) { + require_js($singlelib); + } + } else { + $libpath = ajax_get_lib($lib); + if (array_search($libpath, $loadlibs) === false) { + $loadlibs[] = $libpath; + + // 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($extracthtml==1) { + 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); + } else if($extracthtml==2) { + 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 { + debugging('Unexpected value for $extracthtml'); + } +} + +/** + * 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; +} + + /** * Debugging aid: serve page as 'application/xhtml+xml' where possible, * and substitute the XHTML strict document type.