Skip to content

Instantly share code, notes, and snippets.

@samueljseay
Last active August 11, 2016 01:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samueljseay/20eb38d7b760ccbb4239 to your computer and use it in GitHub Desktop.
Save samueljseay/20eb38d7b760ccbb4239 to your computer and use it in GitHub Desktop.
YUI module loading extension for System.js
(function yui() {
var systemInstantiate = System.instantiate,
//Store just one Y sandbox
YSandbox;
//Extracts the dependency list from the YUI module source code (if any exist)
function getYUIDeps(src, Y, load) {
var stripRequire = /(\"requires\"|\'requires\'|\s*requires\s*)\s*:\s*/g,
findRequire = /(\"requires\"|\'requires\'|\s*requires\s*)\s*:\s*\[[\s\S]*?\](\s*,\s*(\"skinnable\"|skinnable|\'skinnable\')\s*:\s*(true|false))*/g,
skinnable = /(\"skinnable\"|skinnable|\'skinnable\')\s*:\s*(true|false)/
splitDeps = /(('|\")(.*?)('|\")(,|\s*))/g;
//I freely admit I am bad at regex. This gets the job done
//find the requires array(s)
var req = src.match(findRequire),
deps = [];
if(req){
req.forEach(function(dep, index, req) {
var depsModified,
skinnableProp = dep.match(skinnable);
// Skinnable modules always have a css file corresponding to the module name
if(skinnableProp && skinnableProp[2].trim() === 'true') {
deps.push(load.name + '.css!');
}
// Strip the require and skinnable statements
depsModified = dep.replace(stripRequire, '');
depsModified = depsModified.replace(skinnable, '');
depsModified = depsModified.match(splitDeps);
if(depsModified) {
depsModified.forEach(function(dep, index, depsModified) {
depsModified[index] = dep.replace(/[\"\',\s]+/gi,'');
});
deps = deps.concat(depsModified);
}
});
if(deps) {
deps.forEach(function(dep, index){
//remove all the commas and junk
deps[index] = dep.replace(/[\"\',\s]+/gi,'');
});
//Don't add dependencies that are already attached. this is mainly to circumvent the fact that yui-base
//is already attached to the YUI seed and when invoked messes with the global YUI object. Basically it just
//doesn't behave quite like a proper module.
deps = deps.filter(function(dep) {
return ! Y.Env._attached[dep];
});
}
}
return deps ? deps : [];
}
System.instantiate = function(load) {
//The YUI file is loaded at this point. This is why we load YUI seed file without Loader. It makes no
//sense for YUI to handle module loading anymore.
if (load.metadata.format == 'yui' ||
//yet another bad regex, this one doesn't support having a comment with the word YUI.add in it in your code :P
//will fix at some point
!load.metadata.format && load.source.match(/YUI\.add\(/)) {
load.metadata.format = 'yui';
if(! YSandbox) {
//Need to think of a sane way to provide the YUI config to the extension.
//Suspect a global is the simplest
if(window.YUI) {
YSandbox = window.YUI({ lang: 'en' });
}
else {
throw new Error('YUI Seed must be loaded to load YUI modules via System.js');
}
}
// don't forget that just like YUI, System.js will need to know what paths to find these modules in
load.metadata.deps = getYUIDeps(load.source, YSandbox, load);
// main execution function
load.metadata.execute = function(require, exports, moduleName) {
System.__exec(load);
//the Y instance becomes the exports
return YSandbox.use(moduleName.id);
}
}
// pass the metadata on to the register extension for instantiate handling now
return systemInstantiate.call(this, load);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment