This document provides an overview on how to include fixes in the upstream YUI library between point releases of that library.
Description of the problem
The problem with this is two-fold:
- it is possible to serve the YUI framework from an externally hosted content-delivery network. Files distributed from the CDN will not include any patches that we have made; and
- when JS files are served from our repository, we serve headers such that browsers will aggressively cache them.
To the CDN issue
In order to work around the CDN issue, we must serve any patched code from our systems. We should preferably still return all other content from the CDN.
To the aggressive browser caching issue
We must use a different URL for any content that we have modified. This is then seen as new content and used instead of the previously cached version. It is, effectively, a new resource.
We introduce two new variables in lib/setup.php:
- a patch level (or revision); and
- a list of modules which have been patched.
Any time that we wish to patch a module we must both:
- add the exact module name to the list of modules; and
- increment the patch revision.
Both of these things must be performed.
This has the following effects:
For CDN delivered content
We add specific module configuration to the YUI_config->modules object which includes the full path on the local server for the module. This:
- uses the combo loader located in theme/yui_combo.php; and
- specifies a modified version number for the YUI library - e.g. for YUI 3.13.0 and a patch level of 4, this version would be '3.13.0_4'.
For locally delivered content
We add a new group object to the YUI_config->groups object which we ship with each page. This:
- specifies each affected module as a list of patterns and modules so that it is used in preference of the standard definition; and
- includes metadata to use the a modified version number for the YUI library - e.g. for YUI 3.13.0 and a patch level of 4, this version would be '3.13.0_4'.
For non combo-loaded content
In order to use the locally hosted version, we *must* use the combo loader. When not using the combo loader, it is not possible to add a revision as the file is served straight from disk and is subject to server caching configuration. We only use the combo loader for the specified module. Other modules continue to be loaded from the file system using the non combo-loaded method.
How to use
Now that you've read all of that, and understand it, in order to include a patched module:
- checkout the YUI project;
- check out the tag for the version used in Moodle (e.g. git checkout v3.13.0);
- patch the module in the YUI src repository;
- run shifter for that module, specifying the --replace-version option to shifter;
- run the YUI unit tests for this module (cd /path/to/yui ; yeti src/<module>/tests/unit/*.html)
- copy the relevant files in the build directory to the correct location in Moodle;
- edit lib/setup.php and find the $CFG->yuipatchlevel variable;
- increment the patchlevel by one;
- add the changed module only to the $CFG->yuipatchedmodules array
If you are patching a module which has sub-modules, only include the affected modules.
Upgrades to YUI
When we include a new version of the YUI library, you must:
- reset the $CFG->yuipatchlevel to 0; and
- empty the $CFG->yuipatchedmodules array.
- check whether the patch has been included and if not, now re-run the initial instructions (e.g. after resetting the patch level). Do NOT forget to rebuild with the correct YUI version number
Scenario: Patching dd-ddm
$CFG->yuipatchlevel = 1; $CFG->yuipatchedmodules = array( 'dd-ddm', );
Scenario: Patching dd-ddm-base
$CFG->yuipatchlevel = 1; $CFG->yuipatchedmodules = array( 'dd-ddm-base', );
Scenario: Patching dd-ddm, and dd-drop, and dd-gestures
$CFG->yuipatchlevel = 2; $CFG->yuipatchedmodules = array( 'dd-ddm', 'dd-dd-drop', 'dd-dd-gestures', );
Scenario: Patching panel, dd-ddm, and dd-drop, and dd-gestures
$CFG->yuipatchlevel = 3; $CFG->yuipatchedmodules = array( 'panel', 'dd-ddm', 'dd-dd-drop', 'dd-dd-gestures', );