API Docs for: 0.2.0
Show:

File: lib/yui.js

/*
 * 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 */

/**
Provides the class foundation of the `app.yui` object.

@module express-yui/lib/yui
**/

'use strict';

var // sub-modules
    seed    = require('./seed'),
    origin  = require('./origin'),
    server  = require('./server'),
    patch   = require('./loader-patch'),

    // utilities
    utils = require('./utils'),
    debug = require('debug')('express:yui');


/**
The `express-yui/lib/yui` exports the class used to create the `app.yui`
member that will be attached to the express app instance. This member
provides a set of functionalities to control the YUI version to be used
on the client as well as on the server.

The following is an example of how these features can be used:

    var express = require('express'),
        expyui = require('express-yui'),
        app = express();

    expyui.extend(app);

    // Set some basic configs
    app.yui.applyConfig({
        fetchCSS: false
    });

    // Call expose middleware when a route match.
    app.get('/index.html', expyui.expose(), anotherRoute);

In the example above, you can see that right after extending the
`app` with `expyui.extend()` a new member is available under `app.yui`,
and it enable us to configure YUI in any way we want.
Also, the `state` of the app will be serialized
per request, and can be used in the template to set up the client
side to run YUI with the same configuration used on the server side.
Here is an example of a handlebars template:

    <script>
    {{{state}}}
    app.yui.use('node', function (Y) {
        Y.one('#content').setContent('<p>Ready!</p>');
    });
    </script>

In this particular case, `state` will hold all the
appropiated settings generated by `expose` middleware.

@class yui
@static
@constructor
@uses utils, seed, origin, server
*/
function YUIClass(app) {
    var YUI;

    this._app = app;
    this._config = {};
    this._clientModules = {};
    this._serverModules = {};

    try {
        YUI = require('yui' + (utils.debugMode ? '/debug' : ''));
    } catch (e) {
        throw new Error('Error trying to require("yui"). ' +
            '`express`, `express-yui` and `yui` are peerDependencies.');
    }

    this.YUI  = YUI.YUI;
    this.version = YUI.YUI.version;
    this.path = YUI.path();
    debug('Using yui@' + this.version + ' from [' + this.path + '] in ' +
            (utils.debugMode ? 'debug' : 'production') + ' mode.');

    // default configuration based on version
    this._config = {
        version: this.version
    };

    // setting some basic values
    app.set('yui default base', app.get('yui default base') || "/");
    app.set('yui default root', app.get('yui default root') || "/");
    app.set('yui combo config', app.get('yui combo config') || utils.DEFAULT_COMBO_CONFIG);
    // assuming default CDN
    this.setCoreFromCDN();

    // Default clientside patches
    this._config.patches = [];

    // Default serverside patches
    this._patches = [];
}

YUIClass.prototype = {

    /**
    Extends the static configuration with the supplier
    object(s). You can use it like this:

        // Disable CSS computations
        app.yui.applyConfig({
            fetchCSS: false
        });

    @method applyConfig
    @public
    @param {Object*} supplier objects to be mixed with the
    static configuration. All available settings
    [from the YUI API Docs](http://yuilibrary.com/yui/docs/api/classes/config.html).
    can be used here.
    @chainable
    **/
    applyConfig: function () {
        this.config.apply(this, Array.prototype.slice.call(arguments));
        return this;
    },

    /**
    Extends the static configuration with the supplier object(s)
    or returns the current static configuration reference. This
    configuration is static, and attached to the server object.
    Once you call `yui.expose()` middleware for the first time,
    this configuration becomes inmutable.

    @method config
    @protected
    @param {Object*} supplier Optional supplier objects
    that, if passed, will be mix with the static configuration.
    @return {object} static configuration
    **/
    config: function () {

        var args = Array.prototype.slice.call(arguments);

        // Mix in current `arguments` into `this._config`
        if (args.length) {
            args.unshift(this._config);
            utils.extend.apply(null, args);
        }

        return this._config;
    },

    /**
    Set up a default group in loader that represents the
    core yui modules to be loaded from YUI CDN.

        app.yui.setCoreFromCDN();

    @method setCoreFromCDN
    @public
    @param {Object} loaderConfig Optional loader configuration
    objects that, if passed, will be mix with the default
    configuration for yui CDN.
    @chainable
    **/
    setCoreFromCDN: function (loaderConfig) {

        var config = this.config(),
            version = this.version;

        // TODO: This should mutate through an API.

        utils.extend(config, {
            base: "http://yui.yahooapis.com/" + version + "/",
            comboBase: "http://yui.yahooapis.com/combo?",
            comboSep: "&",
            root: version + "/",
            filter: (utils.debugMode ? 'debug' : 'min'),
            logLevel: (utils.debugMode ? 'warn' : 'error'),
            combine: !utils.debugMode
        }, loaderConfig);

        return this;

    }

};

utils.extend(YUIClass.prototype, seed, origin, server, patch);

module.exports = YUIClass;