Plato on Github
Report Home
src/require.js
Maintainability
74.69
Lines of code
151
Difficulty
19.11
Estimated Errors
0.52
Function weight
By Complexity
By SLOC
/** * @file Require implementation * @since 0.2.2 */ /*#ifndef(UMD)*/ "use strict"; /*global _gpfArrayForEach*/ // Almost like [].forEach (undefined are also enumerated) /*global _gpfPathJoin*/ // Join all arguments together and normalize the resulting path /*global _gpfRequireConfigure*/ // Configure the {@link gpf.require} layer /*global _gpfRequireLoad*/ // Load the resource /*exported _gpfRequireAllocate*/ // Allocate a new require context with the proper methods /*#endif*/ /* this is globally used as the current context in this module */ /*jshint -W040*/ /*eslint-disable no-invalid-this*/ /** * @typedef gpf.typedef._requireContext * @property {String} base Base path used to resolve names * @property {Object} cache Dictionary of loaded requires * @property {Object} preload Dictionary of preloaded requires * @property {gpf.typedef.requirePreprocessFunc} preprocess Preprocess function * @since 0.2.2 */ /** * Resolves the resource name according to current require context. * * @param {String} name Relative resource name * @return {String} Resolved name * @since 0.2.2 * */ function _gpfRequireResolve (name) { return _gpfPathJoin(this.base, name); } function _gpfRequireDocumentStack (reason, name) { if (!Array.isArray(reason.requires)) { reason.requires = []; } reason.requires.push(name); } /** * Get the cached resource or load it * * @param {String} name Resource name * @return {Promise<*>} Resource association * @since 0.2.2 */ function _gpfRequireGet (name) { var me = this, promise; if (me.cache[name]) { return me.cache[name]; } promise = _gpfRequireLoad.call(me, name); me.cache[name] = promise; return promise["catch"](function (reason) { _gpfRequireDocumentStack(reason, name); return Promise.reject(reason); }); } /** * Defines a new module by executing the factory function with the specified dependent resources, * see {@tutorial REQUIRE} * * * @param {Object} dependencies Dictionary of dependencies, the keys are preserved while passing the result * dictionary to the factory function * @param {*} factory Can be either: * * A factory function executed when all resources are resolved, the first parameter will be a dictionary * with all dependencies indexed by their name (as initially specified in the dependencies parameter). * The result of the factory function will be cached as the result of this resource * * Any value that will be cached as the result of this resource * @return {Promise<*>} Resolved with the factory function result or the object * @since 0.2.2 */ function _gpfRequireDefine (dependencies, factory) { var me = this, promises = [], keys = Object.keys(dependencies); _gpfArrayForEach(keys, function (key) { promises.push(_gpfRequireGet.call(me, _gpfRequireResolve.call(me, dependencies[key]))); }, me); return Promise.all(promises) .then(function (resources) { var result, require; if (typeof factory === "function") { require = {}; _gpfArrayForEach(keys, function (key, index) { require[key] = resources[index]; }); result = factory(require); } else { result = factory; } return result; }); } /** * Allocate a new require context with the proper methods * * @param {Object} parentContext Context to inherit from * @param {gpf.typedef.requireOptions} [options] Options to configure * @return {Object} Containing {@link gpf.require.define}, {@link gpf.require.resolve} and {@link gpf.require.configure} * @since 0.2.2 */ function _gpfRequireAllocate (parentContext, options) { var context = Object.create(parentContext), // cache content is shared but other properties are protected require = {}; require.define = _gpfRequireDefine.bind(context); require.resolve = _gpfRequireResolve.bind(context); require.configure = _gpfRequireConfigure.bind(context); if (options) { require.configure(options); } return require; } gpf.require = _gpfRequireAllocate({ base: "", cache: {}, preload: {}, preprocess: function (resource) { return Promise.resolve(resource); } }); /** * @method gpf.require.define * @gpf:sameas _gpfRequireDefine * @since 0.2.2 */ /** * @method gpf.require.resolve * @gpf:sameas _gpfRequireResolve * @since 0.2.2 * * @example <caption>Setting the base path</caption> * gpf.require.configure({ * base: "/test/require" * }); * assert(gpf.require.resolve("file.js") === "/test/require/file.js"); */