UNPKG

lfr-amd-loader

Version:

AMD Loader with support for combo URL and conditional loading

244 lines (188 loc) 8.03 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: dependency-builder.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: dependency-builder.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Creates an instance of DependencyBuilder class. * * @constructor * @param {object} - instance of {@link ConfigParser} object. */ function DependencyBuilder(configParser) { this._configParser = configParser; this._result = []; } DependencyBuilder.prototype = { constructor: DependencyBuilder, /** * Resolves modules dependencies. * * @param {array} modules List of modules which dependencies should be resolved. * @return {array} List of module names, representing module dependencies. Module name itself is being returned too. */ resolveDependencies: function (modules) { // Copy the passed modules to a resolving modules queue. // Modules may be added there during the process of resolving. this._queue = modules.slice(0); var result; try { this._resolveDependencies(); // Reorder the modules list so the modules without dependencies will // be moved upfront result = this._result.reverse().slice(0); } finally { this._cleanup(); } return result; }, /** * Clears the used resources during the process of resolving dependencies. * * @protected */ _cleanup: function () { var modules = this._configParser.getModules(); // Set to false all temporary markers which were set during the process of // dependencies resolving. for (var key in modules) { /* istanbul ignore else */ if (hasOwnProperty.call(modules, key)) { var module = modules[key]; module.conditionalMark = false; module.mark = false; module.tmpMark = false; } } this._queue.length = 0; this._result.length = 0; }, /** * Processes conditional modules. If a module has conditional module as dependency, this module will be added to * the list of modules, which dependencies should be resolved. * * @protected * @param {object} module Module, which will be checked for conditional modules as dependencies. */ _processConditionalModules: function (module) { var conditionalModules = this._configParser.getConditionalModules()[module.name]; // If the current module has conditional modules as dependencies, // add them to the list (queue) of modules, which have to be resolved. if (conditionalModules &amp;&amp; !module.conditionalMark) { var modules = this._configParser.getModules(); for (var i = 0; i &lt; conditionalModules.length; i++) { var conditionalModule = modules[conditionalModules[i]]; if (this._queue.indexOf(conditionalModule.name) === -1 &amp;&amp; this._testConditionalModule(conditionalModule.condition.test)) { this._queue.push(conditionalModule.name); } } module.conditionalMark = true; } }, /** * Processes all modules in the {@link DependencyBuilder#_queue} and resolves their dependencies. The function * implements standard * [topological sorting based on depth-first search]{@link http://en.wikipedia.org/wiki/Topological_sorting}. * * @protected */ _resolveDependencies: function () { // Process all modules in the queue. // Note: modules may be added to the queue during the process of evaluating. var modules = this._configParser.getModules(); for (var i = 0; i &lt; this._queue.length; i++) { var module = modules[this._queue[i]]; if (!module.mark) { this._visit(module); } } }, /** * Executes the test function of an conditional module and adds it to the list of module dependencies if the * function returns true. * * @param {function|string} testFunction The function which have to be executed. May be Function object or string. * @return {boolean} The result of the execution of the test function. */ _testConditionalModule: function (testFunction) { if (typeof testFunction === 'function') { return testFunction(); } else { return eval('false || ' + testFunction)(); } }, /** * Visits a module during the process of resolving dependencies. The function will throw exception in case of * circular dependencies among modules. * * @protected * @param {object} module The module which have to be visited. */ _visit: function (module) { // Directed Acyclic Graph is supported only, throw exception if there are circular dependencies. if (module.tmpMark) { throw new Error('Error processing module: ' + module.name + '. ' + 'The provided configuration is not Directed Acyclic Graph.'); } // Check if this module has conditional modules and add them to the queue if so. this._processConditionalModules(module); if (!module.mark) { module.tmpMark = true; var modules = this._configParser.getModules(); for (var i = 0; i &lt; module.dependencies.length; i++) { var dependencyName = module.dependencies[i]; if (dependencyName === 'exports') { continue; } // Map the modules to their aliases dependencyName = this._configParser.mapModule(dependencyName); var moduleDependency = modules[dependencyName]; if (!moduleDependency) { throw new Error('Cannot resolve module: ' + module.name + ' ' + 'due to not yet registered or wrongly specified dependency: ' + dependencyName); } this._visit(moduleDependency, modules); } module.mark = true; module.tmpMark = false; this._result.unshift(module.name); } }, /** * @property {array} _queue List of modules, which dependencies should be resolved. Initially, it is copy of * the array of modules, passed for resolving; during the process more modules may be added to the queue. For * example, these might be conditional modules. * * @protected * @memberof! DependencyBuilder# * @default [] */ _queue: [] };</code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="ConfigParser.html">ConfigParser</a></li><li><a href="DependencyBuilder.html">DependencyBuilder</a></li><li><a href="EventEmitter.html">EventEmitter</a></li><li><a href="Loader.html">Loader</a></li><li><a href="URLBuilder.html">URLBuilder</a></li></ul><h3>Events</h3><ul><li><a href="Loader.html#event:moduleRegister">moduleRegister</a></li></ul> </nav> <br clear="both"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha5</a> on Tue Jun 16 2015 17:51:36 GMT+0200 (CEST) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>