API Docs for: 0.6.0
Show:

File: src/loader.js


    /**
     * Loads dependencies for external functions.
     * 
     * Dependencies:
     * 
     *   - sgvizler.util
     *   - sgvizler.logger
     *   - sgvizler.registry
     *   - jQuery
     *   - google.load
     * 
     * @class sgvizler.loader
     * @static
     */
    S.loader = (function () {

        /*global $ */

        // Module dependencies:
        var util = S.util,
            logger = S.logger,
            registry = S.registry,
            moduleGooVis = registry.GVIZ,
            moduleGooMap = registry.GMAP,

            /** 
             * Contains a list of dependency loaders: function
             * name--deferred pairs. Keeps track of dependencies which
             * have already been asked for (but possibly not been
             * loaded yet).
             * 
             * @property loaders
             * @type Object
             * @private
             * @since 0.6.0
             **/
            loaders = {},

            /**
             * @method loadGVizScript
             * @private
             * @param {Array} [packages] List of
             * `google.visualization` packages to load.
             * @param {boolean} [loadLib] True if
             * `google.visualization` should be loaded even if
             * `packages` array is empty. This is needed in order to
             * load the `DataTable` class, which belongs to no
             * package.
             * @return {jQuery.Promise} Promise object which resolves
             * the loading of the given packages/library.
             * @since 0.6.0
             **/
            loadGVizScript = function (packages, loadLib) {
                /*global google */
                var loader,
                    promise = {},
                    packs = util.removeDuplicates(packages).sort(),
                    options;

                if (packs.length || loadLib) {
                    loader = $.Deferred();
                    options = {
                        callback: function () {
                            loader.resolve();
                            loaders[moduleGooVis].resolve(); // Always resolve google visualization loader.
                            logger.log("loadGVizScript: packages LOADED: " + packs);
                        }
                    };

                    if (packs.length) {
                        options.packages = packs;
                    }
                    google.load('visualization', '1', options);
                    logger.log("loadGVizScript: loading packages: " + packs);

                    promise = loader.promise();
                }

                return promise;
            },

            /**
             * @method loadGMapScript
             * @private
             * @return {jQuery.Promise} Promise object which resolves
             * the loading of google.maps.
             * @since 0.6.0
             **/
            loadGMapScript = function () {
                /*global google */
                var loader = $.Deferred(),
                    options = {
                        other_params: "sensor=false",
                        callback: function () {
                            loader.resolve();
                            logger.log("loadGVizScript: google.maps. LOADED: ");
                        }
                    };
                google.load('maps', '3', options);
                logger.log("loadGMapScript: loading google.maps.");

                return loader.promise();
            },

            /**
             * Load the dependencies of all the given function
             * names---as specified in `sgvizler.registry`.
             * @method loadDependencies
             * @protected
             * @param {Array|string} functions A list of function
             * names (or just a single function name) to load
             * dependencies for.
             * @return {jQuery.Promise} A promise object which
             * resolves the loading of all function dependencies.
             * @example loadDependencies('google.visualization.Map');
             *     returns deferred which will load the dependencies
             *     for the `google.visualization.Map` function as
             *     specified by `sgvizler.registry`.
             * @since 0.6.0
             **/
            loadDependencies = function (functions) {
                var i, ilen,
                    func,
                    deferreds = [], // Collect an array of deferreds.
                    gVizPacks = [],    // List of google visualization packages to collect.
                    gLoader,
                    deps,
                    dep,
                    loadGLib;

                functions = util.removeDuplicates(util.toArray(functions));

                while (functions.length) {

                    func = functions.pop();
                    deps = registry.getDependencies(func);

                    for (dep in deps) {
                        if (deps.hasOwnProperty(dep)) {
                            // Dependency is already loaded/loading.
                            if (loaders[deps[dep]]) {
                                deferreds.push(loaders[deps[dep]]);
                            } else if (util.getObjectByPath(dep) === undefined) {
                                // If it is a googleViz function, then collect package in an array.
                                if (util.startsWith(dep, moduleGooVis)) {
                                    // Special handling of DataTable.
                                    if (dep === registry.DATATABLE) {
                                        loadGLib = true;
                                        loaders[deps[dep]] = $.Deferred();
                                    } else {
                                        gVizPacks.push(deps[dep]);
                                    }
                                } else if (util.startsWith(dep, moduleGooMap)) {
                                    loaders[deps[dep]] = loadGMapScript();
                                    deferreds.push(loaders[deps[dep]]);
                                    logger.log("loadDependencies: loading script: " + deps[dep]);
                                } else {
                                    // Assume dependency is a link to a javascript.
                                    loaders[deps[dep]] = $.getScript(deps[dep])
                                        .done(function () { logger.log("loadDependencies: loaded: " + deps[dep]); });
                                    deferreds.push(loaders[deps[dep]]);
                                    logger.log("loadDependencies: loading script: " + deps[dep]);
                                }
                            }
                        }
                    }
                }
                // If there are GViz packages, collect them to one deferred.
                if (gVizPacks.length || loadGLib) {
                    gLoader = loadGVizScript(gVizPacks, loadGLib);
                    deferreds.push(gLoader);

                    // Register this gLoader with all input function
                    // dependencies solved by this loader.
                    for (i = 0, ilen = gVizPacks.length; i < ilen; i += 1) {
                        loaders[gVizPacks[i]] = gLoader;
                    }
                }
                // Sending array of arguments to when(). See http://bugs.jquery.com/ticket/8256.
                return $.when.apply($, deferreds);
            };

        /////////////////////////////////////////////////
        // PUBLICs

        return {
            loadDependencies: loadDependencies
        };
    }());