MDL-43952 Javascript: Support invalidation of browser caches for YUI patching

This will also force files loaded from the CDN to instead come from the
local distribution since those patches will not be included in the CDN
release.

Please see the documentation at http://docs.moodle.org/dev/YUI/Patching for
important on using these changes.
This commit is contained in:
Andrew Nicols 2014-02-03 11:59:26 +08:00
parent 183515da23
commit aea2973734
5 changed files with 103 additions and 11 deletions

View File

@ -195,6 +195,15 @@ class page_requirements_manager {
$this->YUI_config->comboBase = $this->yui3loader->comboBase;
$this->YUI_config->combine = $this->yui3loader->combine;
// If we've had to patch any YUI modules between releases, we must override the YUI configuration to include them.
// For important information on patching YUI modules, please see http://docs.moodle.org/dev/YUI/Patching.
if (!empty($CFG->yuipatchedmodules) && !empty($CFG->yuipatchlevel)) {
$this->YUI_config->define_patched_core_modules($this->yui3loader->local_comboBase,
$CFG->yui3version,
$CFG->yuipatchlevel,
$CFG->yuipatchedmodules);
}
$configname = $this->YUI_config->set_config_source('lib/yui/config/yui2.js');
$this->YUI_config->add_group('yui2', array(
// Loader configuration for our 2in3, for now ignores $CFG->useexternalyui.
@ -1773,6 +1782,59 @@ class YUI_config {
}
return $modules;
}
/**
* Define YUI modules which we have been required to patch between releases.
*
* We must do this because we aggressively cache content on the browser, and we must also override use of the
* external CDN which will serve the true authoritative copy of the code without our patches.
*
* @param String combobase The local combobase
* @param String yuiversion The current YUI version
* @param Int patchlevel The patch level we're working to for YUI
* @param Array patchedmodules An array containing the names of the patched modules
* @return void
*/
public function define_patched_core_modules($combobase, $yuiversion, $patchlevel, $patchedmodules) {
// The version we use is suffixed with a patchlevel so that we can get additional revisions between YUI releases.
$subversion = $yuiversion . '_' . $patchlevel;
if ($this->comboBase == $combobase) {
// If we are using the local combobase in the loader, we can add a group and still make use of the combo
// loader. We just need to specify a different root which includes a slightly different YUI version number
// to include our patchlevel.
$patterns = array();
$modules = array();
foreach ($patchedmodules as $modulename) {
// We must define the pattern and module here so that the loader uses our group configuration instead of
// the standard module definition. We may lose some metadata provided by upstream but this will be
// loaded when the module is loaded anyway.
$patterns[$modulename] = array(
'group' => 'yui-patched',
);
$modules[$modulename] = array();
}
// Actually add the patch group here.
$this->add_group('yui-patched', array(
'combine' => true,
'root' => $subversion . '/',
'patterns' => $patterns,
'modules' => $modules,
));
} else {
// The CDN is in use - we need to instead use the local combobase for this module and override the modules
// definition. We cannot use the local base - we must use the combobase because we cannot invalidate the
// local base in browser caches.
$fullpathbase = $combobase . $subversion . '/';
foreach ($patchedmodules as $modulename) {
$this->modules[$modulename] = array(
'fullpath' => $fullpathbase . $modulename . '/' . $modulename . '-min.js'
);
}
}
}
}
/**

View File

@ -349,6 +349,15 @@ if (!defined('AJAX_SCRIPT')) {
$CFG->yui2version = '2.9.0';
$CFG->yui3version = '3.13.0';
// Patching the upstream YUI release.
// For important information on patching YUI modules, please see http://docs.moodle.org/dev/YUI/Patching.
// If we need to patch a YUI modules between official YUI releases, the yuipatchlevel will need to be manually
// incremented here. The module will also need to be listed in the yuipatchedmodules.
// When upgrading to a subsequent version of YUI, these should be reset back to 0 and an empty array.
$CFG->yuipatchlevel = 0;
$CFG->yuipatchedmodules = array(
);
// Store settings from config.php in array in $CFG - we can use it later to detect problems and overrides.
if (!isset($CFG->config_php_settings)) {
$CFG->config_php_settings = (array)$CFG;

View File

@ -12,6 +12,9 @@ Description of import of various YUI libraries into Moodle:
* update lib/thrirdpartylibs.xml
* verify our simpleyui rollup contents in /theme/yui_combo.php
If you need to patch the YUI library between its official releases, you *must* read
http://docs.moodle.org/dev/YUI/Patching.
3/ YUI3 Gallery version gallery-2013.10.02-20-26:
* selective copy of the "build" directory for the checked out tag of yui3-gallery.
Unit test code coverage files (*-coverage.js) are removed but no other changes are made.

View File

@ -102,6 +102,11 @@ while (count($parts)) {
continue;
}
// Allow support for revisions on YUI between official releases.
// We can just discard the subrevision since it is only used to invalidate the browser cache.
$yuipatchedversion = explode('_', $revision);
$yuiversion = $yuipatchedversion[0];
$yuimodules = array(
// Include everything from original SimpleYUI,
// this list can be built using http://yuilibrary.com/yui/configurator/ by selecting all modules
@ -193,14 +198,14 @@ while (count($parts)) {
if ($type === 'js') {
$newparts = array();
foreach ($yuimodules as $module) {
$newparts[] = $revision . '/' . $module . '/' . $module . $filesuffix;
$newparts[] = $yuiversion . '/' . $module . '/' . $module . $filesuffix;
}
$newparts[] = 'yuiuseall/yuiuseall';
$parts = array_merge($newparts, $parts);
} else {
$newparts = array();
foreach ($yuimodules as $module) {
$candidate = $revision . '/' . $module . '/assets/skins/sam/' . $module . '.css';
$candidate = $yuiversion . '/' . $module . '/assets/skins/sam/' . $module . '.css';
if (!file_exists("$CFG->libdir/yuilib/$candidate")) {
continue;
}
@ -306,10 +311,17 @@ while (count($parts)) {
$filecontent = "var Y = YUI().use('*');";
} else {
if ($version != $CFG->yui3version) {
// Allow support for revisions on YUI between official releases.
// We can just discard the subrevision since it is only used to invalidate the browser cache.
$yuipatchedversion = explode('_', $version);
$yuiversion = $yuipatchedversion[0];
if ($yuiversion != $CFG->yui3version) {
$content .= "\n// Wrong yui version $part!\n";
continue;
}
$newpart = explode('/', $part);
$newpart[0] = $yuiversion;
$part = implode('/', $newpart);
$contentfile = "$CFG->libdir/yuilib/$part";
}
if (!file_exists($contentfile) or !is_file($contentfile)) {

View File

@ -63,15 +63,21 @@ if ($version == 'moodle' && count($parts) >= 3) {
} else if ($version == 'gallery' && count($parts) >= 3) {
list($revision, $module, , , , $image) = $parts;
$imagepath = "$CFG->dirroot/lib/yuilib/gallery/$module/assets/skins/sam/$image";
} else if (count($parts) == 1 && ($version == $CFG->yui3version || $version == $CFG->yui2version)) {
list($image) = $parts;
if ($version == $CFG->yui3version) {
$imagepath = "$CFG->dirroot/lib/yuilib/$CFG->yui3version/assets/skins/sam/$image";
} else {
$imagepath = "$CFG->dirroot/lib/yuilib/2in3/$CFG->yui2version/build/assets/skins/sam/$image";
}
} else {
yui_image_not_found();
// Allow support for revisions on YUI between official releases.
// We can just discard the subrevision since it is only used to invalidate the browser cache.
$yuipatchedversion = explode('_', $version);
$yuiversion = $yuipatchedversion[0];
if (count($parts) == 1 && ($yuiversion == $CFG->yui3version || $yuiversion == $CFG->yui2version)) {
list($image) = $parts;
if ($yuiversion == $CFG->yui3version) {
$imagepath = "$CFG->dirroot/lib/yuilib/$CFG->yui3version/assets/skins/sam/$image";
} else {
$imagepath = "$CFG->dirroot/lib/yuilib/2in3/$CFG->yui2version/build/assets/skins/sam/$image";
}
} else {
yui_image_not_found();
}
}
if (!file_exists($imagepath)) {