From a3024011a91d3941f81481dd4d600e9684eb0fd4 Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Thu, 2 Feb 2012 00:11:51 -0800 Subject: upgrading to Montage v0.6 Signed-off-by: Valerio Virgillito --- node_modules/montage/require/require.js | 997 +++++++++++++------------------- 1 file changed, 412 insertions(+), 585 deletions(-) (limited to 'node_modules/montage/require/require.js') diff --git a/node_modules/montage/require/require.js b/node_modules/montage/require/require.js index 988dd811..8273b660 100755 --- a/node_modules/montage/require/require.js +++ b/node_modules/montage/require/require.js @@ -3,12 +3,37 @@ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. */ -bootstrap("require/require", function (require, CJS) { - var Promise = require("core/promise").Promise; - var URL = require("core/url"); +(function (definition) { - var global = (function () {return this})(); + // Boostrapping Browser + if (typeof bootstrap !== "undefined") { + bootstrap("require/require", function (require, exports) { + var Promise = require("core/promise").Promise; + var URL = require("core/mini-url"); + definition(exports, Promise, URL); + require("require/browser"); + }); + + // Node Server + } else if (typeof process !== "undefined") { + var Promise = (require)("../core/promise").Promise; + var URL = (require)("../core/url"); + definition(exports, Promise, URL); + require("./node"); + if (require.main == module) + exports.main(); + + } else { + throw new Error("Can't support require on this platform"); + } + +})(function (Require, Promise, URL) { + + if (!this) + throw new Error("Require does not work in strict mode."); + + var global = this; var globalEval = eval; // reassigning causes eval to not use lexical scope. // Non-CommonJS speced extensions should be marked with an "// EXTENSION" comment. @@ -17,228 +42,192 @@ bootstrap("require/require", function (require, CJS) { // Returns the root "require" function. If this root "require()" function is called the loader will be in synchronous mode. // To get asynchronous loading you MUST call the root "require.async()". In async mode all subsequent calls to "require()" will // be asynchronously loaded, and synchronously executed. - CJS.Sandbox = function(config) { + Require.Sandbox = function(config) { // Configuration defaults: config = config || {}; - config.location = URL.resolve(config.location || CJS.pwd(), "."); + config.location = URL.resolve(config.location || Require.getLocation(), "."); config.lib = URL.resolve(config.location, config.lib || "."); config.paths = config.paths || [config.lib]; config.mappings = config.mappings || {}; // EXTENSION - config.definitions = config.definitions || {}; - config.modules = config.modules || {}; - config.exposedConfigs = config.exposedConfigs || [ - "paths", - "mappings", - "loader", - "definitions", - "base", - "location", - "packageDescription", - "loadPackage" - ]; - config.makeLoader = config.makeLoader || CJS.DefaultLoaderConstructor; - config.loader = config.loader || config.makeLoader(config); - config.makeCompiler = config.makeCompiler || CJS.DefaultCompilerConstructor; - config.compiler = config.compiler || config.makeCompiler(config); + config.exposedConfigs = config.exposedConfigs || Require.defaultExposedConfigs; + config.makeLoader = config.makeLoader || Require.DefaultLoaderConstructor; + config.load = config.load || config.makeLoader(config); + config.makeCompiler = config.makeCompiler || Require.DefaultCompilerConstructor; + config.compile = config.compile || config.makeCompiler(config); // Sandbox state: - // Module instances: { exports, id, path, uri } - var modules = config.modules; - // Module definition objects: { factory, dependencies, path } - var definitions = config.definitions; - // Arrays of callbacks to be executed once a module definition has been loaded - var definitionListeners = {}; + // Modules: { exports, id, location, directory, factory, dependencies, dependees, text, type } + var modules = config.modules = config.modules || {}; // Mapping from canonical IDs to the initial top ID used to load module - var urisToIds = {}; - - // Ensures a module definition is loaded before returning or executing the callback. - // Supports multiple calls for the same topId by registering callback as a listener if it has already been initiated. - function loadDefinition(topId, callback) { - if (callback) { - // already loaded - if (has(definitions, topId) && definitions[topId].factory) { - callback(topId); - } - // in progress - else if (has(definitionListeners, topId)) { - definitionListeners[topId].push(callback); - } - // pre-arranged - else if (has(definitions, topId) && definitions[topId].path !== undefined) { - var def = definitions[topId]; - CJS.read(def.path).then(function (text) { - def.text = text; - config.compiler(def); - callback(topId); - }, function (reason) { - console.warn("Can't read " + JSON.stringify(def.path) + ": " + reason); - callback(null); - }); - } - // hasn't started - else { - definitionListeners[topId] = [callback]; + var locationsToIds = {}; - config.loader(topId, function(definition) { - if (!definition) { - CJS.warn("Can't find module " + JSON.stringify(topId)); - } - definitions[topId] = definition || null; - - CJS.progress.loadedModules.push([ - config.location, - topId - ].join("#")); + function getModule(id) { + if (!has(modules, id)) { + modules[id] = { + id: id, + display: config.location + "#" + id // EXTENSION + }; + } + return modules[id]; + } + config.module = getModule; - definitionListeners[topId].forEach(function(fn) { - fn(topId); - }); + function inject(id, exports) { + var module = getModule(id) + module.exports = exports; + module.location = URL.resolve(config.location, id); + module.directory = URL.resolve(module.location, "."); + } + // Ensures a module definition is loaded, compiled, analyzed + var load = memoize(function (topId, viaId) { + var module = getModule(topId); + return Promise.call(function () { + // already loaded, already instantiated, or redirection + if ( + module.factory !== void 0 || + module.exports !== void 0 || + module.redirect !== void 0 + ) { + return module; + // load + } else { + Require.progress.requiredModules.push(module.display); + return Promise.call(config.load, null, topId, module) + .then(function () { + Require.progress.loadedModules.push(module.display); + return module; }); } - } else { - // already loaded - if (has(definitions, topId)) { - return; - } - // hasn't started - else { - var definition = config.loader(topId); - if (!definition) { - CJS.warn("Can't find module " + JSON.stringify(topId)); - } - definitions[topId] = definition || null; + }) + .then(function (module) { + // analyze dependencies + config.compile(module); + var dependencies = module.dependencies = module.dependencies || []; + if (module.redirect !== void 0) { + dependencies.push(module.redirect); } - } + return module; + }); + }); + + // Load a module definition, and the definitions of its transitive + // dependencies + function deepLoad(id, viaId, loading) { + // this is a memo of modules already being loaded so we don’t + // data-lock on a cycle of dependencies. + loading = loading || {}; + // has this all happened before? will it happen again? + if (has(loading, id)) + return; // break the cycle of violence. + loading[id] = true; // this has happened before + return load(id, viaId) + .then(function (module) { + // load the transitive dependencies using the magic of + // recursion. + return Promise.all(module.dependencies.map(function (depId) { + depId = resolve(depId, id) + // create dependees set, purely for debug purposes + var module = getModule(depId); + var dependees = module.dependees = module.dependees || {}; + dependees[id] = true; + return deepLoad(depId, id, loading); + })) + .then(function () { + return module; + }) + }) } - function loadDeepDefinitions(topId, callback) { - if (has(modules, topId)) { - CJS.warn("module already init (1): " + topId); - return callback && callback(); + // Initializes a module by executing the factory function with a new module "exports" object. + function getExports(topId, viaId) { + var module = getModule(topId); + + // handle redirects + if (module.redirect !== void 0) { + return getExports(module.redirect, viaId); } - if (callback) { - // in async mode we need to load the transitive dependencies first - var transitiveDependencies = {}; // undefined = not yet seen; false = not yet loaded; true = already loaded; - var loaded = false; - function loadDependencies(id) { - transitiveDependencies[id] = true; - if (definitions[id]) { - (definitions[id].dependencies || []).map(function(dependency) { - var depId = resolve(dependency, id); - if (!has(transitiveDependencies, depId)) { - transitiveDependencies[depId] = false; - return depId; - } - }).forEach(function(depId) { - depId && loadDefinition(depId, loadDependencies); - }); - } - // if any dependency is still unloaded, bail early - // TODO: could eliminate this loop by counting - for (var dependency in transitiveDependencies) { - if (transitiveDependencies[dependency] === false) { - return; - } - } - // otherwise we're done loading transitive dependencies - if (!loaded) { - loaded = true; - callback(); - } - } - // kick it off with the root module: - loadDefinition(topId, loadDependencies); - } else { - loadDefinition(topId); + + // handle cross-package linkage + if (module.mappingRedirect !== void 0) { + return module.mappingRequire(module.mappingRedirect, viaId); } - } - // Loads module definition (and it's transitive dependencies if in async loading mode) then initializes the module. - function loadModule(topId) { - var result = Promise.defer(); + // do not reinitialize modules + if (module.exports !== void 0) { + return module.exports; + } - // Update the list of modules that need to load - CJS.progress.requiredModules.push( - [config.location, topId].join("#") + // do not initialize modules that do not define a factory function + if (module.factory === void 0) { + throw new Error("Can't require module " + JSON.stringify(topId) + " via " + JSON.stringify(viaId)); + } + + module.directory = URL.resolve(module.location, "."); // EXTENSION + module.exports = {}; + + // Execute the factory function: + var returnValue = module.factory.call( + // in the context of the module: + global, // this + makeRequire(topId), // require + module.exports, // exports + module // module ); - loadDeepDefinitions(topId, function () { - try { - initModule(topId); - result.resolve(); - } catch (exception) { - result.reject(exception.message, exception); - } - }); + // Modules should never have a return value. + if (returnValue !== void 0) { + console.warn('require: module "'+topId+'" returned a value.'); + } - return result.promise; - } + // Update the list of modules that are ready to use + Require.progress.initializedModules.push(module.display); - // Initializes a module by executing the factory function with a new module "exports" object. - function initModule(topId) { - if (has(definitions, topId)) { - if (definitions[topId] && typeof definitions[topId].factory === "function") { - // HACK: look up canonical URI in previously initialized modules (different topId, same URI) - // TODO: Handle this at higher level? - var uri = URL.resolve(definitions[topId].path, ""); - if (has(urisToIds, uri)) { - var canonicalId = urisToIds[uri]; - modules[topId] = modules[canonicalId]; - } else { - urisToIds[uri] = topId; - - var module = modules[topId] = { - exports: {}, - id: topId, - path: definitions[topId].path, - directory: URL.resolve(definitions[topId].path, "."), - uri: uri // EXTENSION - }; - - var requireArg = makeRequire(topId); - var exportsArg = module.exports; - var moduleArg = module; - - // Execute the factory function: - var returnValue = definitions[topId].factory.call(global, requireArg, exportsArg, moduleArg); - - // Modules should never have a return value. - if (returnValue !== undefined) { - CJS.warn('require: module "'+topId+'" returned a value.'); - } - - // Update the list of modules that are ready to use - CJS.progress.initializedModules.push([ - config.location, - topId - ].join("#")); + return module.exports; + } - } + // Finds the internal identifier for a module in a subpackage + // The ``internal`` boolean parameter causes the function to return + // null instead of throwing an exception. I’m guessing that + // throwing exceptions *and* being recursive would be too much + // performance evil for one function. + function identify(id2, require2, internal) { + if (require2.location === config.location) + return id2; + var locations = {}; + for (var name in config.mappings) { + var mapping = config.mappings[name]; + var location = mapping.location; + var candidate = config.getPackage(location); + var id1 = candidate.identify(id2, require2, true); + if (id1 === null) { + continue + } else if (id1 === "") { + return name; } else { - CJS.warn("Can't require module "+JSON.stringify(topId)); - throw new Error("Can't require module "+JSON.stringify(topId)); + return name + "/" + id1; } + } + if (internal) { + return null; } else { - CJS.error("Can't require module "+JSON.stringify(topId)+": not yet loaded."); + throw new Error("Can't identify " + id2 + " from " + require2.location); } } // Creates a unique require function for each module that encapsulates that module's id for resolving relative module IDs against. - function makeRequire(base) { + function makeRequire(viaId) { + // Main synchronously executing "require()" function var require = function(id) { - var topId = resolve(id, base); - if (!modules[topId]) { - initModule(topId); - } - return modules[topId].exports; + var topId = resolve(id, viaId); + return getExports(topId, viaId); }; // Asynchronous "require.async()" which ensures async executation (even with synchronous loaders) require.async = function(id, callback) { - var topId = resolve(id, base); - return loadModule(topId) + var topId = resolve(id, viaId); + return deepLoad(topId, viaId) .then(function () { return require(topId); }) @@ -251,41 +240,18 @@ bootstrap("require/require", function (require, CJS) { } return rejection; }); - }; - require.deepLoader = loadDeepDefinitions; - - // Finds the internal identifier for a module in a subpackage - // The ``internal`` boolean parameter causes the function to return - // null instead of throwing an exception. I’m guessing that - // throwing exceptions *and* being recursive would be too much - // performance evil for one function. - require.identify = function (id2, require2, internal) { - if (require2.location === require.location) - return id2; - var locations = {}; - for (var name in config.mappings) { - var mapping = config.mappings[name]; - var location = mapping.location; - var candidate = config.getPackage(location); - var id1 = candidate.identify(id2, require2, true); - if (id1 === null) { - continue - } else if (id1 === "") { - return name; - } else { - return name + "/" + id1; - } - } - if (internal) { - return null; - } else { - throw new Error("Can't identify " + id2 + " from " + require2.location); - } + require.resolve = function (id) { + return resolve(id, viaId); }; - require.progress = CJS.progress; + require.load = load; + require.deepLoad = deepLoad; + require.loadPackage = config.loadPackage; + require.identify = identify; + require.inject = inject; + require.progress = Require.progress; config.exposedConfigs.forEach(function(name) { require[name] = config[name]; @@ -299,87 +265,17 @@ bootstrap("require/require", function (require, CJS) { return makeRequire(""); }; - CJS.progress = { + Require.progress = { requiredModules: [], loadedModules: [], initializedModules: [] }; - function makeDefine() { - var subscribers = []; - var define = function() { - var definition = parseDefine(Array.prototype.slice.call(arguments)); - definition.path = getCurrentScriptURL(); - for (var i = 0; i < subscribers.length; i++) { - if (typeof subscribers[i] === "function") { - subscribers[i](definition); - } - } - } - // API for loaders to "subscribe" to define calls - define._subscribe = function(subscriber) { - subscribers.push(subscriber); - } - return define; - } - - function parseDefine(args) { - var definition = {}; - - // optional: module id - if (typeof args[0] === "string") { - definition.id = args.shift(); - } - // optional: module dependencies - if (Array.isArray(args[0])) { - definition.dependencies = args.shift(); - } - // required: module factory or exports object - if (typeof args[0] === "function") { - definition.factory = args.shift(); - } else if (typeof args[0] === "object") { - var exportsObject = args.shift(); - definition.factory = function(require, exports, module) { - module.exports = exportsObject; - }; - } - - if (args.length > 0 || typeof definition.factory !== "function") { - CJS.console.warn("Invalid module definition: ", args); - } - - return definition; - } - - // TODO: other engines - function getStack() { - var stack = new Error().stack; - return stack && stack.split("\n").slice(1).map(function(l) { - var m = l.match(/^ at (?:([\w\.]+) \()?([^()]+?)(?::(\d+))?(?::(\d+))?\)?$/); - return m && { method : m[1], url : m[2], line : parseInt(m[3], 10), column : parseInt(m[4], 10) }; - }); - } - - function getCurrentScriptURL() { - if (document.currentScript) { - return document.currentScript.src || null; - } else { - var frames, last; - return (frames = getStack()) && (last = frames.pop()) && last.url || null - } - } - - if (!global.define) { - global.define = makeDefine(); - } else { - CJS.warn("define already exists."); - } - - CJS.PackageSandbox = function (location, config) { + Require.PackageSandbox = function (location, config) { location = URL.resolve(location, "."); config = config || {}; - var packages = config.packages = config.packages || {}; - var loadedPackages = {}; + var loadingPackages = config.loadingPackages = config.loadingPackages || {}; + var loadedPackages = config.packages = {}; config.getPackage = function (dependency) { dependency = Dependency(dependency); @@ -394,22 +290,26 @@ bootstrap("require/require", function (require, CJS) { dependency = Dependency(dependency); // TODO handle other kinds of dependency var location = URL.resolve(dependency.location, "."); - if (!packages[location]) { + if (!loadingPackages[location]) { var jsonPath = URL.resolve(location, 'package.json'); - packages[location] = CJS.read(jsonPath) + loadingPackages[location] = Require.read(jsonPath) .then(function (json) { - var packageDescription = JSON.parse(json); + try { + var packageDescription = JSON.parse(json); + } catch (exception) { + throw new SyntaxError("in " + JSON.stringify(jsonPath) + ": " + exception.message); + } var subconfig = configurePackage( location, packageDescription, config ); - var pkg = CJS.Sandbox(subconfig); + var pkg = Require.Sandbox(subconfig); loadedPackages[location] = pkg; return pkg; }); } - return packages[location]; + return loadingPackages[location]; }; var _require = config.loadPackage(location); @@ -432,22 +332,25 @@ bootstrap("require/require", function (require, CJS) { function configurePackage(location, description, parent) { + if (!/\/$/.test(location)) { + location += "/"; + } + var config = Object.create(parent); config.name = description.name; - config.location = location; + config.location = location || Require.getLocation(); config.packageDescription = description; // explicitly mask definitions and modules, which must // not apply to child packages - var definitions = config.definitions = {}; - config.modules = {}; + var modules = config.modules = config.modules || {}; // overlay var overlay = description.overlay || {}; - CJS.overlays.forEach(function (engine) { + Require.overlays.forEach(function (engine) { if (overlay[engine]) { layer = overlay[engine]; for (var name in layer) { - info[name] = layer[name]; + description[name] = layer[name]; } } }); @@ -455,29 +358,34 @@ bootstrap("require/require", function (require, CJS) { // directories description.directories = description.directories || {}; - description.directories.lib = description.directories.lib === undefined ? "." : description.directories.lib; + description.directories.lib = description.directories.lib === void 0 ? "." : description.directories.lib; var lib = description.directories.lib; // lib - config.lib = location + "/" + lib; + config.lib = URL.resolve(location, "./" + lib); var packageRoot = description.directories.packages || "node_modules"; packageRoot = URL.resolve(location, packageRoot + "/"); - // name, creates an alias for the module name within - // its package. For example, in the "q" package, one - // can require("q") to get the main module. - if (description.name) - definitions[description.name] = {"ref": ""}; - // The default "main" module of a package has the same name as the // package. - if (description.main === undefined) - description.main = description.name; + if (description.main !== void 0) { + + // main, injects a definition for the main module, with + // only its path. makeRequire goes through special effort + // in deepLoad to re-initialize this definition with the + // loaded definition from the given path. + modules[""] = { + id: "", + redirect: description.main, + location: config.location + }; + + modules[description.name] = { + id: description.name, + redirect: "", + location: URL.resolve(location, description.name) + }; - // main, injects a definition for the main module, with - // only its path. makeRequire goes through special effort - // in deepLoad to re-initialize this definition with the - // loaded definition from the given path. - definitions[""] = {"path": URL.resolve(location, description.main)}; + } // mappings, link this package to other packages. var mappings = description.mappings || {}; @@ -495,8 +403,10 @@ bootstrap("require/require", function (require, CJS) { }); Object.keys(mappings).forEach(function (name) { var mapping = mappings[name] = Dependency(mappings[name]); - if (!CJS.isAbsolute(mapping.location)) - mapping.location = URL.resolve(location + "/", mapping.location + "/"); + if (!/\/$/.test(mapping.location)) + mapping.location += "/"; + if (!Require.isAbsolute(mapping.location)) + mapping.location = URL.resolve(location, mapping.location); }); config.mappings = mappings; @@ -511,12 +421,28 @@ bootstrap("require/require", function (require, CJS) { }; // Resolves CommonJS module IDs (not paths) + Require.resolve = resolve; function resolve(id, baseId) { id = String(id); - if (id.charAt(0) == ".") { - id = URL.resolve(URL.resolve(baseId, "."), id); + var source = id.split("/"); + var target = []; + if (source.length && source[0] === "." || source[0] === "..") { + var parts = baseId.split("/"); + parts.pop(); + source.unshift.apply(source, parts); + } + for (var i = 0, ii = source.length; i < ii; i++) { + var part = source[i]; + if (part === "" || part === ".") { + } else if (part === "..") { + if (target.length) { + target.pop(); + } + } else { + target.push(part); + } } - return URL.resolve(id, ""); + return target.join("/"); }; // ES5 shim: @@ -540,43 +466,20 @@ bootstrap("require/require", function (require, CJS) { }; } - CJS.base = function (path) { + Require.base = function (location) { // matches Unix basename - return String(path) + return String(location) .replace(/(.+?)\/+$/, "$1") .match(/([^\/]+$|^\/$|^$)/)[1]; }; - // Tests whether the path or URL is a absolute. - CJS.isAbsolute = function(path) { - var parsed = URL.parse(path); - return parsed.authorityRoot || parsed.root; + // Tests whether the location or URL is a absolute. + Require.isAbsolute = function(location) { + return /^\w+:/.test(location); }; - // Attempts to return a standardized error object. - CJS.standardizeError = function(e, defaults) { - var error = { - name : e.name, - message : e.message, - line : e.line || e.lineNumber, - url : e.fileName, - stack : e.stack - }; - for (var name in defaults) { - if (has(defaults, name) && !error[name]) { - error[name] = defaults[name]; - } - } - return error; - } - - // Takes a standardized error (see CJS.standardizeError) and returns a string appropriate for error reporting - CJS.syntaxErrorFormatter = function(e) { - return e.name + (e.message ? " ("+e.message+")" : "") + " on line " + (e.line || "[unknown]") + " of " + e.url; - } - // Extracts dependencies by parsing code and looking for "require" (currently using a simple regexp) - CJS.parseDependencies = function(factory) { + Require.parseDependencies = function(factory) { var o = {}; String(factory).replace(/(?:^|[^\w\$_.])require\s*\(\s*["']([^"']*)["']\s*\)/g, function(_, id) { o[id] = true; @@ -584,288 +487,212 @@ bootstrap("require/require", function (require, CJS) { return Object.keys(o); }; - // Executes a function asynchronously using whatever mechaism is available to the platform - // Used to ensure asynchronicity even when loader doesn't support async. - CJS.executeAsynchronously = function(fn) { - if (typeof setTimeout === "function") { - setTimeout(fn, 1); - } else { - CJS.warn("CJS warning: Implement CJS.executeAsynchronously(fn) for your platform."); - fn(); - } - }; - // Built-in compiler/preprocessor "middleware": - // Compiles module text into a function. - // Can be overriden by the platform to make the engine aware of the source path. Uses sourceURL hack by default. - CJS.NewFunctionCompiler = function(config) { - config.scope = config.scope || {}; - var names = ["require", "exports", "module"]; - var scopeNames = Object.keys(config.scope); - names.push.apply(names, scopeNames); - return function(def) { - if (!def.factory && def.text !== undefined) { - var factory = globalEval( - "(function(" + names.join(",") + "){" + - def.text + - "\n//*/\n})\n//@ sourceURL=" + def.path - ); - def.factory = function (require, exports, module) { - Array.prototype.push.apply(arguments, scopeNames.map(function (name) { - return config.scope[name]; - })); - return factory.apply(this, arguments); - }; - // new Function will have its body reevaluated at every call, hence using eval instead - // https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope - //def.factory = new Function("require", "exports", "module", def.text + "\n//*/\n//@ sourceURL="+def.path); - delete def.text; + Require.DependenciesCompiler = function(config, compile) { + return function(module) { + if (!module.dependencies && module.text !== void 0) { + module.dependencies = Require.parseDependencies(module.text); } - return def; - }; - }; - - CJS.ParseDependencies = function(config, compiler) { - return function(def) { - if (!def.dependencies && def.text !== undefined) { - def.dependencies = CJS.parseDependencies(def.text); - } - def = compiler(def); - if (def && !def.dependencies) { - if (def.text || def.factory) { - def.dependencies = CJS.parseDependencies(def.text || def.factory); + compile(module); + if (module && !module.dependencies) { + if (module.text || module.factory) { + module.dependencies = Require.parseDependencies(module.text || module.factory); } else { - def.dependencies = []; + module.dependencies = []; } } - return def; - }; - }; - - CJS.CatchExceptions = function(config, compiler) { - return function(def) { - try { - return compiler(def); - } catch (e) { - CJS.error(CJS.syntaxErrorFormatter(CJS.standardizeError(e, { name : "SyntaxError", url : def.path }))); - return null; - } + return module; }; }; // Support she-bang for shell scripts by commenting it out (it is never valid JavaScript syntax anyway) - CJS.StripShebang = function(config, compiler) { - return function(def) { - if (def.text) { - def.text = def.text.replace(/^#!/, "//#!"); + Require.ShebangCompiler = function(config, compile) { + return function (module) { + if (module.text) { + module.text = module.text.replace(/^#!/, "//#!"); } - return compiler(def); + compile(module); } }; - function runJSHint(text, path, options) { - if (!JSHINT(text, options)) { - console.warn("JSHint Error: "+path); - JSHINT.errors.forEach(function(error) { - if (error) { - console.warn("Problem at line "+error.line+" character "+error.character+": "+error.reason); - if (error.evidence) { - console.warn(" " + error.evidence); - } - } - }); + Require.LintCompiler = function(config, compile) { + if (!config.lint) { + return compile; } - } - - CJS.JSHint = function(config, compiler) { - if (typeof JSHINT !== "function") { - return compiler; - } - - return function(def) { + return function(module) { try { - return compiler(def); - } catch (e) { - runJSHint(def.text, def.path, config.jslintOptions); - return null; + compile(module); + } catch (error) { + config.lint(module); + throw error; } - } + }; } - CJS.DefaultCompilerMiddleware = function(config, compiler) { - return CJS.CatchExceptions(config, - CJS.StripShebang(config, - CJS.ParseDependencies(config, - CJS.JSHint(config, compiler)))); - }; - - CJS.DefaultCompilerConstructor = function(config) { - return CJS.DefaultCompilerMiddleware(config, CJS.NewFunctionCompiler(config)); + Require.defaultExposedConfigs = [ + "paths", + "mappings", + "location", + "packageDescription", + "packages", + "modules", + "module" + ]; + + Require.DefaultCompilerConstructor = function(config) { + return Require.ShebangCompiler( + config, + Require.DependenciesCompiler( + config, + Require.LintCompiler( + config, + Require.Compiler(config) + ) + ) + ); }; // Built-in loader "middleware": - // Attempts to load using multiple loaders until one of them works: - CJS.Multi = function(config, loaders) { - return function(id, callback) { - return tryEachSyncOrAsync(loaders, function(loader, resultCallback) { - return loader(id, resultCallback); - }, callback); - }; - }; - - // Attempts to load using multiple base paths (or one absolute path) with a single loader. - CJS.Paths = function(config, loader) { - return function(id, callback) { - var paths = CJS.isAbsolute(id) ? - [id] : - config.paths.map(function(path) { - return URL.resolve(path, id); - }); - - return tryEachSyncOrAsync(paths, function(path, resultCallback) { - return loader(path, resultCallback); - }, callback); - }; + Require.DefaultLoaderConstructor = function(config) { + return Require.MappingsLoader( + config, + Require.ExtensionsLoader( + config, + Require.PathsLoader( + config, + Require.MemoizedLoader( + config, + Require.Loader(config) + ) + ) + ) + ); }; // Using mappings hash to load modules that match a mapping. - CJS.Mappings = function(config, next) { + Require.MappingsLoader = function(config, load) { config.mappings = config.mappings || {}; config.name = config.name || ""; - return function(id, callback) { - if (CJS.isAbsolute(id)) - return next(id, callback); + + var mappings = config.mappings; + var prefixes = Object.keys(mappings); + var length = prefixes.length; + + // finds a mapping to follow, if any + return function (id, module) { + if (Require.isAbsolute(id)) { + return load(id, module); + } // TODO: remove this when all code has been migrated off of the autonomous name-space problem - if (id.indexOf(config.name) === 0 && id.charAt(config.name.length) === "/") + if (id.indexOf(config.name) === 0 && id.charAt(config.name.length) === "/") { console.warn("Package reflexive module ignored:", id); - if (id === config.name) - id = ""; - // The package loader can inject some definitions for - // aliases into the package configuration. These will - // only have path attributes and need to be replaced with - // factories. We intercept these aliases (usually the - // package's main module, not found in its lib path) here. - if (config.definitions[id]) { - return next(config.definitions[id].path, callback); } - return tryEachSyncOrAsync(Object.keys(config.mappings), function(candidate, resultCallback) { + var i, prefix + for (i = 0; i < length; i++) { + prefix = prefixes[i]; if ( - id === candidate || - id.indexOf(candidate) === 0 && id.charAt(candidate.length) === "/" + id === prefix || + id.indexOf(prefix) === 0 && + id.charAt(prefix.length) === "/" ) { - var location = config.mappings[candidate].location; - return config.loadPackage(location).then(function (pkg) { - var rest = id.slice(candidate.length + 1); - pkg.deepLoader(rest, function (result) { - resultCallback({ - "factory": function (require, exports, module) { - module.exports = pkg(rest); - }, - "path": location + "#" + rest // this is necessary for constructing unique URI's for chaching - }); - }); - }, function (reason) { - return resultCallback ? resultCallback(null) : null; + var mapping = mappings[prefix]; + var rest = id.slice(prefix.length + 1); + return config.loadPackage(mapping) + .then(function (mappingRequire) { + module.mappingRedirect = rest; + module.mappingRequire = mappingRequire; + return mappingRequire.deepLoad(rest, config.location); }); - } else { - return resultCallback ? resultCallback(null) : null; - } - }, function (result) { - if (result) { - if (callback) { - callback(result); - } else { - return result; - } - } else { - return next(id, callback); } - }); + } + return load(id, module); }; }; - CJS.Extensions = function(config, loader) { + Require.ExtensionsLoader = function(config, load) { var extensions = config.extensions || ["js"]; - return function(id, callback) { - var needsExtension = CJS.base(id).indexOf(".") < 0; - return tryEachSyncOrAsync(extensions, function(extension, resultCallback) { - if (needsExtension) - return loader(id + "." + extension, resultCallback); - else - return loader(id, resultCallback); - }, callback); + var loadWithExtension = extensions.reduceRight(function (next, extension) { + return function (id, module) { + return load(id + "." + extension, module) + .fail(function (error) { + return next(id, module); + }); + }; + }, function (id, module) { + throw new Error( + "Can't find " + JSON.stringify(id) + " with extensions " + + JSON.stringify(extensions) + " in package at " + + JSON.stringify(config.location) + ); + }); + return function (id, module) { + if (Require.base(id).indexOf(".") !== -1) { + // already has an extension + return load(id, module); + } else { + return loadWithExtension(id, module); + } } } - // Special helper function that iterates over each item calling iteratorCallback until success (calls completeCallback - // with a truthy value, or returns a truthy value otherwise). Useful in "middleware" like Paths, Multi, etc. - function tryEachSyncOrAsync(items, iteratorCallback, completeCallback) { - if (completeCallback) { - var i = 0; - function tryNext() { - if (i >= items.length) { - return completeCallback(null); - } else { - return iteratorCallback(items[i++], function(result) { - return result ? completeCallback(result) : tryNext(); - }); - } - } - return tryNext(); - } else { - for (var i = 0; i < items.length; i++) { - var result = iteratorCallback(items[i]); - if (result) { - return result; - } + // Attempts to load using multiple base paths (or one absolute path) with a single loader. + Require.PathsLoader = function(config, load) { + var loadFromPaths = config.paths.reduceRight(function (next, path) { + return function (id, module) { + var newId = URL.resolve(path, id); + return load(newId, module) + .fail(function () { + return next(id, module); + }); + }; + }, function (id, module) { + throw new Error("Can't find " + JSON.stringify(id) + " from paths " + JSON.stringify(config.paths) + " in package at " + JSON.stringify(config.location)); + }); + return function(id, module) { + if (Require.isAbsolute(id)) { + // already fully qualified + return load(id, module); + } else { + return loadFromPaths(id, module); } - return null; - } + }; }; - CJS.CachingLoader = function(config, loader) { - var cache = {}; - var pending = {}; - return function(url, callback) { - url = URL.resolve(url, ""); - - if (has(cache, url)) { - return callback ? callback(cache[url]) : cache[url]; - } + Require.MemoizedLoader = function (config, load) { + var cache = config.cache = config.cache || {}; + return memoize(load, cache); + }; - if (callback) { - if (has(pending, url)) { - pending[url].push(callback); + Require.Loader = function (config, load) { + return function (url, module) { + return Require.read(url) + .then(function (text) { + module.type = "javascript"; + module.text = text; + module.location = url; + }, function (reason, error, rejection) { + // This is a hook that allows a Loader to be chained to a + // fallback, such as the NodeLoader, if a local module can’t be + // found. + if (load) { + return load(url, module); } else { - pending[url] = [callback]; - loader(url, function(definition) { - cache[url] = definition; - pending[url].forEach(function(pendingCallback) { - pendingCallback(definition); - }); - }); + return rejection; } - } else { - return cache[url] = loader(url); - } - } - } - - if (typeof console === "undefined") { - console = {} - console.log = - console.warn = - console.error = function () {}; - } + }); + }; + }; - CJS.enableLogging = false; - CJS.log = - CJS.warn = - CJS.error = function () { - if (CJS.enableLogging) - console.log.apply(console, arguments); + var memoize = function (callback, cache) { + cache = cache || {}; + return function (key, arg) { + if (!has(cache, key)) { + cache[key] = Promise.call(callback, null, key, arg); + } + return cache[key]; + }; }; }); -- cgit v1.2.3