yui-pathogen-encoder
Version:
Enables pathogen encoding in YUI Loader
196 lines (149 loc) • 6.5 kB
JavaScript
/*
* Copyright (c) 2013, Yahoo! Inc. All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
/*jslint node:true, nomen: true */
/**
The `express-yui.origin` extension that provides a set of features
to mutate the express app into an origin server for yui
modules and static assets.
@module yui
@submodule origin
**/
'use strict';
var libpath = require('path'),
utils = require('./utils');
/**
The `express-yui.origin` extension that provides some basic configuration
that will facilitate the configuration of YUI Core modules and other
groups to be served from the express app in a form of origin server.
This is not recommended for production and instead you should use the
`cdn` module, but it is a very useful feature for development of offline
applications.
var express = require('express'),
expyui = require('express-yui'),
app = express();
expyui.extend(app);
// getting YUI Core modules from the app origin.
app.yui.setCoreFromAppOrigin();
// registering a group `app` based on a folder generated by `shifter` module
app.yui.registerGroup('app', '/path/to/foo/yui-build');
app.use(expyui.static());
@class origin
@static
@uses utils, *path
@extensionfor yui
*/
module.exports = {
/**
Set YUI Core Modules from the same origin as to where the application
is hosted.
Here is an example on how to use it:
app.yui.setCoreFromAppOrigin({});
@method setCoreFromAppOrigin
@public
@param {Object} loaderConfig optional loader configuration for the core
@chainable
**/
setCoreFromAppOrigin: function (loaderConfig) {
var groupDefaultBase = this._app.set('yui default base') || "/{{groupDir}}/",
groupDefaultRoot = this._app.set('yui default root') || "/{{groupDir}}/",
comboConfig = this._app.set('yui combo config') || utils.DEFAULT_COMBO_CONFIG,
config = this.config(),
yuiDir = 'yui-' + this.version;
loaderConfig = loaderConfig || {};
loaderConfig = utils.extend(config, comboConfig, {
base: groupDefaultBase,
root: groupDefaultRoot
}, loaderConfig);
// fixed base and root for this group
// replace groupName and groupDirname
loaderConfig.base = loaderConfig.base.replace("{{groupDir}}", yuiDir);
loaderConfig.root = loaderConfig.root.replace("{{groupDir}}", yuiDir);
return this;
},
/**
Set a custom loader configuration for the group.
Here is an example of how to use it.
app.yui.applyGroupConfig('app', {
maxURLLength: 2048,
comboBase: "/combo?"
comboSep: "&"
});
@method applyGroupConfig
@public
@param {String} groupName the name of the group used by loader.
@param {Object} loaderConfig custom loader configuration
for the group.
@chainable
**/
applyGroupConfig: function (groupName, loaderConfig) {
var config = this.config();
loaderConfig = loaderConfig || {};
// setting up the group base config if needed
config.groups = config.groups || {};
config.groups[groupName] = config.groups[groupName] || {};
config.groups[groupName] = utils.extend(config.groups[groupName], loaderConfig);
return this;
},
/**
Register a group and its modules by analyzing the meta file and defining the
group configuration for the loader. Groups can be served from origin app or
from CDN by calling `applyGroupConfig` or by setting `yui default base`,
`yui default root` and `yui combo config` thru `app.set()`.
Here is an example on how to use it, assuming that the YUI metadata are
located in the `build` directory under the app root.
app.yui.registerGroup('app', __dirname + '/build');
@method registerGroup
@public
@param {String} groupName the name of the group used by loader.
@param {String} groupRoot filesystem path for the group. This will be used to
analyze all modules in the group.
@param {String} metaFile optional filesystem path for the yui module that holds
the metas for the group. Default value: `<groupRoot>/<groupName>/<groupName>.js`
@chainable
**/
registerGroup: function (groupName, groupRoot, metaFile) {
var groupDefaultBase = this._app.set('yui default base') || "/{{groupDir}}/",
groupDefaultRoot = this._app.set('yui default root') || "/{{groupDir}}/",
comboConfig = this._app.set('yui combo config') || utils.DEFAULT_COMBO_CONFIG,
group,
groupConfig,
config,
groupDir = libpath.basename(groupRoot);
metaFile = metaFile || libpath.join(groupRoot, groupName, groupName + '.js');
// collect the group information from the meta file
group = this.getGroupConfig(metaFile);
if (!group) {
throw new Error("Invalid meta file [" + metaFile + "], " +
"it contains no group.");
}
if (groupName !== group.groupName) {
throw new Error("Mismatch between the groupName [" + groupName +
"] and the group registered in [" + metaFile + "].");
}
config = this.config();
config.groups = config.groups || {};
// setting up the default group config
groupConfig = config.groups[groupName] = utils.extend({
base: groupDefaultBase,
root: groupDefaultRoot,
// inherit combine
combine: config.hasOwnProperty('combine') ? config.combine : true,
// inherit filter
filter: config.hasOwnProperty('filter') ? config.filter : 'min'
}, comboConfig, config.groups[groupName] || {});
// replace groupName and groupDirname
groupConfig.base = groupConfig.base.replace("{{groupDir}}", groupDir);
groupConfig.root = groupConfig.root.replace("{{groupDir}}", groupDir);
// storing the root path to the group in case we
// need it later to server the group from origin server
this._groupFolderMap = this._groupFolderMap || {};
this._groupFolderMap[groupName] = groupRoot;
// add the meta module into the core structure
// to make sure it gets attached to Y upfront
this.addModuleToSeed(group.moduleName, groupName);
return this;
}
};