/* This file contains proprietary software owned by Motorola Mobility, Inc.
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"); var global = (function () {return this})(); var globalEval = eval; // reassigning causes eval to not use lexical scope. // Non-CommonJS speced extensions should be marked with an "// EXTENSION" comment. // Sandbox is an instance of the loader system. Different sandboxes will have different instances of modules. // 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) { // Configuration defaults: config = config || {}; config.location = URL.resolve(config.location || CJS.pwd(), "."); 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); // 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 = {}; // 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]; 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("#")); definitionListeners[topId].forEach(function(fn) { fn(topId); }); }); } } 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; } } } function loadDeepDefinitions(topId, callback) { if (has(modules, topId)) { CJS.warn("module already init (1): " + topId); return callback && callback(); } 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); } } // Loads module definition (and it's transitive dependencies if in async loading mode) then initializes the module. function loadModule(topId) { var result = Promise.defer(); // Update the list of modules that need to load CJS.progress.requiredModules.push( [config.location, topId].join("#") ); loadDeepDefinitions(topId, function () { try { initModule(topId); result.resolve(); } catch (exception) { result.reject(exception.message, exception); } }); return result.promise; } // 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("#")); } } else { CJS.warn("Can't require module "+JSON.stringify(topId)); throw new Error("Can't require module "+JSON.stringify(topId)); } } else { CJS.error("Can't require module "+JSON.stringify(topId)+": not yet loaded."); } } // Creates a unique require function for each module that encapsulates that module's id for resolving relative module IDs against. function makeRequire(base) { // Main synchronously executing "require()" function var require = function(id) { var topId = resolve(id, base); if (!modules[topId]) { initModule(topId); } return modules[topId].exports; }; // Asynchronous "require.async()" which ensures async executation (even with synchronous loaders) require.async = function(id, callback) { var topId = resolve(id, base); return loadModule(topId) .then(function () { return require(topId); }) .then(function (exports) { callback && callback(exports); return exports; }, function (reason, error, rejection) { if (callback) { console.error(error.stack); } 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.progress = CJS.progress; config.exposedConfigs.forEach(function(name) { require[name] = config[name]; }); require.config = config; return require; } return makeRequire(""); }; CJS.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) { location = URL.resolve(location, "."); config = config || {}; var packages = config.packages = config.packages || {}; var loadedPackages = {}; config.getPackage = function (dependency) { dependency = Dependency(dependency); // TODO handle other kinds of dependency var location = dependency.location; if (!loadedPackages[location]) throw new Error("Dependency is not loaded: " + JSON.stringify(location)); return loadedPackages[location]; }; config.loadPackage = function (dependency) { dependency = Dependency(dependency); // TODO handle other kinds of dependency var location = URL.resolve(dependency.location, "."); if (!packages[location]) { var jsonPath = URL.resolve(location, 'package.json'); packages[location] = CJS.read(jsonPath) .then(function (json) { var packageDescription = JSON.parse(json); var subconfig = configurePackage( location, packageDescription, config ); var pkg = CJS.Sandbox(subconfig); loadedPackages[location] = pkg; return pkg; }); } return packages[location]; }; var _require = config.loadPackage(location); _require.location = location; _require.async = function (id, callback) { return _require.then(function (require) { return require.async(id, callback); }); }; return _require; }; function Dependency(dependency) { if (typeof dependency === "string") { dependency = {"location": dependency}; } return dependency; } function configurePackage(location, description, parent) { var config = Object.create(parent); config.name = description.name; config.location = location; config.packageDescription = description; // explicitly mask definitions and modules, which must // not apply to child packages var definitions = config.definitions = {}; config.modules = {}; // overlay var overlay = description.overlay || {}; CJS.overlays.forEach(function (engine) { if (overlay[engine]) { layer = overlay[engine]; for (var name in layer) { info[name] = layer[name]; } } }); delete description.overlay; // directories description.directories = description.directories || {}; description.directories.lib = description.directories.lib === undefined ? "." : description.directories.lib; var lib = description.directories.lib; // lib config.lib = 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; // 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 || {}; // dependencies var dependencies = description.dependencies || {}; Object.keys(dependencies).forEach(function (name) { var versionPredicateString = dependencies[name]; // TODO (version presently ignored for debug mode) if (!mappings[name]) { mappings[name] = {"location": URL.resolve( packageRoot, name + "/" )}; } }); 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 + "/"); }); config.mappings = mappings; return config; } // Helper functions: function has(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // Resolves CommonJS module IDs (not paths) function resolve(id, baseId) { id = String(id); if (id.charAt(0) == ".") { id = URL.resolve(URL.resolve(baseId, "."), id); } return URL.resolve(id, ""); }; // ES5 shim: // ES5 15.4.3.2 if (!Array.isArray) { Array.isArray = function(obj) { return Object.prototype.toString.call(obj) == "[object Array]"; }; } // ES5 15.2.3.14 if (!Object.keys) { Object.keys = function(object) { var keys = []; for (var name in object) { if (Object.prototype.hasOwnProperty.call(object, name)) { keys.push(name); } } return keys; }; } CJS.base = function (path) { // matches Unix basename return String(path) .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; }; // 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) { var o = {}; String(factory).replace(/(?:^|[^\w\$_.])require\s*\(\s*["']([^"']*)["']\s*\)/g, function(_, id) { o[id] = true; }); 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; } 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); } else { def.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; } }; }; // 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(/^#!/, "//#!"); } return compiler(def); } }; 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); } } }); } } CJS.JSHint = function(config, compiler) { if (typeof JSHINT !== "function") { return compiler; } return function(def) { try { return compiler(def); } catch (e) { runJSHint(def.text, def.path, config.jslintOptions); return null; } } } 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)); }; // 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); }; }; // Using mappings hash to load modules that match a mapping. CJS.Mappings = function(config, next) { config.mappings = config.mappings || {}; config.name = config.name || ""; return function(id, callback) { if (CJS.isAbsolute(id)) return next(id, callback); // 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) === "/") 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) { if ( id === candidate || id.indexOf(candidate) === 0 && id.charAt(candidate.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; }); } else { return resultCallback ? resultCallback(null) : null; } }, function (result) { if (result) { if (callback) { callback(result); } else { return result; } } else { return next(id, callback); } }); }; }; CJS.Extensions = function(config, loader) { 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); } } // 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; } } 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]; } if (callback) { if (has(pending, url)) { pending[url].push(callback); } else { pending[url] = [callback]; loader(url, function(definition) { cache[url] = definition; pending[url].forEach(function(pendingCallback) { pendingCallback(definition); }); }); } } 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); }; });