todomvc
Version:
> Helping you select an MV\* framework
1,246 lines (1,106 loc) • 1.41 MB
JavaScript
BUNDLE=[["index.html.bundle-1-0.js","index.html.bundle-1-1.js","index.html.bundle-1-2.js","index.html.bundle-1-3.js"]];
;
//*/
/* <copyright>
Copyright (c) 2012, Motorola Mobility LLC.
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Motorola Mobility LLC nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</copyright> */
/*global BUNDLE */
if (typeof window !== "undefined") {
// Workaround for window.Touch on desktop browsers
if (!("ontouchstart" in window)) {
window.Touch = null;
}
document._montageTiming = {}
document._montageTiming.loadStartTime = Date.now();
// Give a threshold before we decide we need to show the bootstrapper progress
// Applications that use our loader will interact with this timeout
// and class name to coordinate a nice loading experience. Applications that do not will
// just go about business as usual and draw their content as soon as possible.
window.addEventListener("DOMContentLoaded", function() {
var bootstrappingDelay = 1000;
document._montageStartBootstrappingTimeout = setTimeout(function() {
document._montageStartBootstrappingTimeout = null;
var root = document.documentElement;
if(!!root.classList) {
root.classList.add("montage-app-bootstrapping");
} else {
root.className = root.className + " montage-app-bootstrapping";
}
document._montageTiming.bootstrappingStartTime = Date.now();
}, bootstrappingDelay);
});
}
(function (definition) {
if (typeof require !== "undefined") {
// CommonJS / NodeJS
definition.call(
typeof global !== "undefined" ? global : this,
require,
exports,
module
);
} else {
// <script>
definition({}, {}, {});
}
})(function (require, exports, module) {
// The global context object
global = this;
/**
* Initializes Montage and creates the application singleton if
* necessary.
*/
exports.initMontage = function () {
var platform = exports.getPlatform();
// Platform dependent
platform.bootstrap(function (Require, Promise, URL) {
var params = platform.getParams();
var config = platform.getConfig();
var montageLocation = URL.resolve(Require.getLocation(), params.montageLocation);
// setup the reel loader
config.makeLoader = function (config) {
return exports.ReelLoader(
config,
Require.makeLoader(config)
);
};
// setup serialization compiler
config.makeCompiler = function (config) {
return exports.MetaCompiler(
config,
exports.SerializationCompiler(
config,
exports.TemplateCompiler(
config,
Require.makeCompiler(config)
)
)
);
};
var location = URL.resolve(config.location, params["package"] || ".");
var applicationHash = params.applicationHash;
if (typeof BUNDLE === "object") {
var bundleDefinitions = {};
var getDefinition = function (name) {
return bundleDefinitions[name] =
bundleDefinitions[name] ||
Promise.defer();
};
global.bundleLoaded = function (name) {
getDefinition(name).resolve();
};
var preloading = Promise.defer();
config.preloaded = preloading.promise;
// preload bundles sequentially
var preloaded = Promise.resolve();
BUNDLE.forEach(function (bundleLocations) {
preloaded = preloaded.then(function () {
return Promise.all(bundleLocations.map(function (bundleLocation) {
browser.load(bundleLocation);
return getDefinition(bundleLocation).promise;
}));
});
});
// then release the module loader to run normally
preloading.resolve(preloaded.then(function () {
delete BUNDLE;
delete bundleLoaded;
}));
}
var applicationRequirePromise;
if (!("remoteTrigger" in params)) {
if ("autoPackage" in params) {
Require.injectPackageDescription(location, {
dependencies: {
montage: "*"
}
}, config);
} else {
// handle explicit package.json location
if (location.slice(location.length - 5) === ".json") {
var packageDescriptionLocation = location;
location = URL.resolve(location, ".");
Require.injectPackageDescriptionLocation(
location,
packageDescriptionLocation,
config
);
}
}
applicationRequirePromise = Require.loadPackage({
location: location,
hash: applicationHash
}, config);
} else {
// allows the bootstrapping to be remote controlled by the
// parent window, with a dynamically generated package
// description
var trigger = Promise.defer();
window.postMessage({
type: "montageReady"
}, "*");
var messageCallback = function (event) {
if (
params.remoteTrigger === event.origin &&
(event.source === window || event.source === window.parent)
) {
switch (event.data.type) {
case "montageInit":
window.removeEventListener("message", messageCallback);
trigger.resolve([event.data.location, event.data.injections]);
break;
case "isMontageReady":
// allow the injector to query the state in case
// they missed the first message
window.postMessage({
type: "montageReady"
}, "*");
}
}
};
window.addEventListener("message", messageCallback);
applicationRequirePromise = trigger.promise.spread(function (location, injections) {
var promise = Require.loadPackage({
location: location,
hash: applicationHash
}, config);
if (injections) {
promise = promise.then(function (applicationRequire) {
location = URL.resolve(location, ".");
var packageDescriptions = injections.packageDescriptions,
packageDescriptionLocations = injections.packageDescriptionLocations,
mappings = injections.mappings,
dependencies = injections.dependencies,
index, injectionsLength;
if (packageDescriptions) {
injectionsLength = packageDescriptions.length;
for (index = 0; index < injectionsLength; index++) {
applicationRequire.injectPackageDescription(
packageDescriptions[index].location,
packageDescriptions[index].description);
}
}
if (packageDescriptionLocations) {
injectionsLength = packageDescriptionLocations.length;
for (index = 0; index < injectionsLength; index++) {
applicationRequire.injectPackageDescriptionLocation(
packageDescriptionLocations[index].location,
packageDescriptionLocations[index].descriptionLocation);
}
}
if (mappings) {
injectionsLength = mappings.length;
for (index = 0; index < injectionsLength; index++) {
applicationRequire.injectMapping(
mappings[index].dependency,
mappings[index].name);
}
}
if (dependencies) {
injectionsLength = dependencies.length;
for (index = 0; index < injectionsLength; index++) {
applicationRequire.injectDependency(
dependencies[index].name,
dependencies[index].version);
}
}
return applicationRequire;
});
}
return promise;
});
}
applicationRequirePromise
.then(function (applicationRequire) {
applicationRequire.loadPackage({
location: montageLocation,
hash: params.montageHash
})
.then(function (montageRequire) {
// load the promise package so we can inject the bootstrapped
// promise library back into it
var promiseLocation;
if (params.promiseLocation) {
promiseLocation = URL.resolve(Require.getLocation(), params.promiseLocation);
} else {
promiseLocation = URL.resolve(montageLocation, "packages/mr/packages/q");
}
return [
montageRequire,
montageRequire.loadPackage({
location: promiseLocation,
hash: params.promiseHash
})
];
})
.spread(function (montageRequire, promiseRequire) {
montageRequire.inject("core/mini-url", URL);
montageRequire.inject("core/promise", {Promise: Promise});
promiseRequire.inject("q", Promise);
// install the linter, which loads on the first error
config.lint = function (module) {
montageRequire.async("core/jshint")
.then(function (JSHINT) {
if (!JSHINT.JSHINT(module.text)) {
console.warn("JSHint Error: "+module.location);
JSHINT.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);
}
}
});
}
})
.done();
};
global.require = applicationRequire;
global.montageRequire = montageRequire;
platform.initMontage(montageRequire, applicationRequire, params);
});
})
.done();
});
};
/**
Adds "_montage_metadata" property to all objects and function attached to
the exports object.
@see Compiler middleware in require/require.js
@param config
@param compiler
*/
var reverseReelExpression = /((.*)\.reel)\/\2$/;
var reverseReelFunction = function ($0, $1) { return $1 };
exports.SerializationCompiler = function(config, compile) {
return function(module) {
compile(module);
if (!module.factory)
return;
var defaultFactory = module.factory;
module.factory = function(require, exports, module) {
defaultFactory.call(this, require, exports, module);
for (var name in exports) {
var object = exports[name];
// avoid attempting to initialize a non-object
if (!(object instanceof Object)) {
// avoid attempting to reinitialize an aliased property
} else if (object.hasOwnProperty("_montage_metadata") && !object._montage_metadata.isInstance) {
object._montage_metadata.aliases.push(name);
object._montage_metadata.objectName = name;
} else if (!Object.isSealed(object)) {
var id = module.id.replace(
reverseReelExpression,
reverseReelFunction
);
Object.defineProperty(
object,
"_montage_metadata",
{
value: {
require: require,
module: id,
moduleId: id, // deprecated
property: name,
objectName: name, // deprecated
aliases: [name],
isInstance: false
}
}
);
}
}
};
return module;
};
};
/**
* Allows reel directories to load the contained eponymous JavaScript
* module.
* @see Loader middleware in require/require.js
* @param config
* @param loader the next loader in the chain
*/
var reelExpression = /([^\/]+)\.reel$/;
exports.ReelLoader = function (config, load) {
return function (id, module) {
var match = reelExpression.exec(id);
if (match) {
module.redirect = id + "/" + match[1];
return module;
} else {
return load(id, module);
}
};
};
/**
* Allows the .meta files to be loaded as json
* @see Compiler middleware in require/require.js
* @param config
* @param compile
*/
var metaExpression = /\.meta/;
exports.MetaCompiler = function (config, compile) {
return function (module) {
var json = (module.location || "").match(metaExpression);
if (json) {
module.exports = JSON.parse(module.text);
return module;
} else {
return compile(module);
}
};
};
/**
Allows the reel's html file to be loaded via require.
@see Compiler middleware in require/require.js
@param config
@param compiler
*/
exports.TemplateCompiler = function(config, compile) {
return function(module) {
if (!module.location)
return;
var match = module.location.match(/(.*\/)?(?=[^\/]+\.html(?:\.load\.js)?$)/);
if (match) {
module.dependencies = module.dependencies || [];
module.exports = {
directory: match[1],
content: module.text
};
// XXX deprecated
Object.defineProperty(module.exports, "root", {
get: function () {
if (typeof console === "object") {
console.warn("'root' property is deprecated on template modules. Use 'directory' instead of root[1]");
}
return match;
}
});
return module;
} else {
compile(module);
}
};
};
// Bootstrapping for multiple-platforms
exports.getPlatform = function () {
if (typeof window !== "undefined" && window && window.document) {
return browser;
} else if (typeof process !== "undefined") {
return require("./node.js");
} else {
throw new Error("Platform not supported.");
}
};
var browser = {
// mini-url library
makeResolve: function () {
var head = document.querySelector("head"),
baseElement = document.createElement("base"),
relativeElement = document.createElement("a");
baseElement.href = "";
return function (base, relative) {
var currentBaseElement = head.querySelector("base");
if (!currentBaseElement) {
head.appendChild(baseElement);
currentBaseElement = baseElement;
}
base = String(base);
if (!/^[\w\-]+:/.test(base)) { // isAbsolute(base)
throw new Error("Can't resolve from a relative location: " + JSON.stringify(base) + " " + JSON.stringify(relative));
}
var restore = currentBaseElement.href;
currentBaseElement.href = base;
relativeElement.href = relative;
var resolved = relativeElement.href;
currentBaseElement.href = restore;
if (currentBaseElement === baseElement) {
head.removeChild(currentBaseElement);
}
return resolved;
};
},
load: function (location) {
var script = document.createElement("script");
script.src = location;
script.onload = function () {
// remove clutter
script.parentNode.removeChild(script);
};
document.getElementsByTagName("head")[0].appendChild(script);
},
getConfig: function() {
return {
location: "" + window.location
};
},
getParams: function() {
var i, j,
match,
script,
montage,
attr,
name;
if (!this._params) {
this._params = {};
// Find the <script> that loads us, so we can divine our
// parameters from its attributes.
var scripts = document.getElementsByTagName("script");
for (i = 0; i < scripts.length; i++) {
script = scripts[i];
montage = false;
if (script.src && (match = script.src.match(/^(.*)montage.js(?:[\?\.]|$)/i))) {
this._params.montageLocation = match[1];
montage = true;
}
if (script.hasAttribute("data-montage-location")) {
this._params.montageLocation = script.getAttribute("data-montage-location");
montage = true;
}
if (montage) {
if (script.dataset) {
for (name in script.dataset) {
this._params[name] = script.dataset[name];
}
} else if (script.attributes) {
var dataRe = /^data-(.*)$/,
letterAfterDash = /-([a-z])/g,
upperCaseChar = function (_, c) {
return c.toUpperCase();
};
for (j = 0; j < script.attributes.length; j++) {
attr = script.attributes[j];
match = attr.name.match(/^data-(.*)$/);
if (match) {
this._params[match[1].replace(letterAfterDash, upperCaseChar)] = attr.value;
}
}
}
// Permits multiple montage.js <scripts>; by
// removing as they are discovered, next one
// finds itself.
script.parentNode.removeChild(script);
break;
}
}
}
return this._params;
},
bootstrap: function (callback) {
var base, Require, DOM, Promise, URL;
var params = this.getParams();
var resolve = this.makeResolve();
// observe dom loading and load scripts in parallel
// observe dom loaded
function domLoad() {
document.removeEventListener("DOMContentLoaded", domLoad, true);
DOM = true;
callbackIfReady();
}
// this permits montage.js to be injected after DOMContentLoaded
// http://jsperf.com/readystate-boolean-vs-regex/2
if (/interactive|complete/.test(document.readyState)) {
domLoad();
} else {
document.addEventListener("DOMContentLoaded", domLoad, true);
}
// determine which scripts to load
var pending = {
"require": "packages/mr/require.js",
"require/browser": "packages/mr/browser.js",
"promise": "packages/mr/packages/q/q.js"
};
// load in parallel, but only if we're not using a preloaded cache.
// otherwise, these scripts will be inlined after already
if (typeof BUNDLE === "undefined") {
var montageLocation = resolve(window.location, params.montageLocation);
for (var id in pending) {
browser.load(resolve(montageLocation, pending[id]));
}
}
// register module definitions for deferred,
// serial execution
var definitions = {};
global.bootstrap = function (id, factory) {
definitions[id] = factory;
delete pending[id];
for (var id in pending) {
// this causes the function to exit if there are any remaining
// scripts loading, on the first iteration. consider it
// equivalent to an array length check
return;
}
// if we get past the for loop, bootstrapping is complete. get rid
// of the bootstrap function and proceed.
delete global.bootstrap;
allModulesLoaded();
};
// one module loaded for free, for use in require.js, browser.js
global.bootstrap("mini-url", function (require, exports) {
exports.resolve = resolve;
});
// miniature module system
var bootModules = {};
function bootRequire(id) {
if (!bootModules[id] && definitions[id]) {
var exports = bootModules[id] = {};
bootModules[id] = definitions[id](bootRequire, exports) || exports;
}
return bootModules[id];
}
// execute bootstrap scripts
function allModulesLoaded() {
URL = bootRequire("mini-url");
Promise = bootRequire("promise");
Require = bootRequire("require");
delete global.bootstrap;
callbackIfReady();
}
function callbackIfReady() {
if (DOM && Require) {
callback(Require, Promise, URL);
}
}
},
initMontage: function (montageRequire, applicationRequire, params) {
var dependencies = [
"core/core",
"core/event/event-manager",
"core/serialization/deserializer/montage-reviver",
"core/logger"
];
var Promise = montageRequire("core/promise").Promise;
return Promise.all(dependencies.map(montageRequire.deepLoad))
.then(function () {
dependencies.forEach(montageRequire);
var Montage = montageRequire("core/core").Montage;
var EventManager = montageRequire("core/event/event-manager").EventManager;
var MontageReviver = montageRequire("core/serialization/deserializer/montage-reviver").MontageReviver;
var logger = montageRequire("core/logger").logger
var defaultEventManager, application;
// Setup Promise's longStackTrace support option
logger("Promise stacktrace support", function(state) {
Promise.longStackSupport = !!state;
});
// Load the event-manager
defaultEventManager = new EventManager().initWithWindow(window);
// montageWillLoad is mostly for testing purposes
if (typeof global.montageWillLoad === "function") {
global.montageWillLoad();
}
// Load the application
var appProto = applicationRequire.packageDescription.applicationPrototype,
applicationLocation, appModulePromise;
if (appProto) {
applicationLocation = MontageReviver.parseObjectLocationId(appProto);
appModulePromise = applicationRequire.async(applicationLocation.moduleId);
} else {
appModulePromise = montageRequire.async("core/application");
}
return appModulePromise.then(function(exports) {
var Application = exports[(applicationLocation ? applicationLocation.objectName : "Application")];
application = new Application();
Object.defineProperty(window.document, "application", {
get: Montage.deprecate(
null,
function () {
return exports.application
},
"document.application is deprecated, use require(\"montage/core/application\").application instead."
)
});
defaultEventManager.application = application;
application.eventManager = defaultEventManager;
application._load(applicationRequire, function() {
if (params.module) {
// If a module was specified in the config then we initialize it now
applicationRequire.async(params.module)
.done();
}
if (typeof global.montageDidLoad === "function") {
global.montageDidLoad();
}
});
})
})
.done();
}
};
if (typeof window !== "undefined") {
if (global.__MONTAGE_LOADED__) {
console.warn("Montage already loaded!");
} else {
global.__MONTAGE_LOADED__ = true;
exports.initMontage();
}
} else {
// may cause additional exports to be injected:
exports.getPlatform();
}
})
;
//*/
/*
Based in part on Motorola Mobility’s Montage
Copyright (c) 2012, Motorola Mobility LLC. All Rights Reserved.
3-Clause BSD License
https://github.com/motorola-mobility/montage/blob/master/LICENSE.md
*/
/*global bootstrap,define */
(function (definition) {
// Boostrapping Browser
if (typeof bootstrap !== "undefined") {
// Window
if (typeof window !== "undefined") {
bootstrap("require", function (require, exports) {
var Promise = require("promise");
var URL = require("mini-url");
definition(exports, Promise, URL);
require("require/browser");
});
// Worker
} else {
bootstrap("require", function (require, exports) {
var Promise = require("promise").Promise;
var URL = require("mini-url");
definition(exports, Promise, URL);
});
}
// Node Server
} else if (typeof process !== "undefined") {
// the parens trick the heuristic scanner for static dependencies, so
// they are not pre-loaded by the asynchronous browser loader
var Promise = (require)("q");
var URL = (require)("url");
definition(exports, Promise, URL);
(require)("./node");
} 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 globalEval = eval; // reassigning causes eval to not use lexical scope.
// Non-CommonJS speced extensions should be marked with an "// EXTENSION"
// comment.
Require.makeRequire = function (config) {
var require;
// Configuration defaults:
config = config || {};
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.exposedConfigs = config.exposedConfigs || Require.exposedConfigs;
config.makeLoader = config.makeLoader || Require.makeLoader;
config.load = config.load || config.makeLoader(config);
config.makeCompiler = config.makeCompiler || Require.makeCompiler;
config.compile = config.compile || config.makeCompiler(config);
config.parseDependencies = config.parseDependencies || Require.parseDependencies;
config.read = config.read || Require.read;
// Modules: { exports, id, location, directory, factory, dependencies,
// dependees, text, type }
var modules = config.modules = config.modules || {};
// produces an entry in the module state table, which gets built
// up through loading and execution, ultimately serving as the
// ``module`` free variable inside the corresponding module.
function getModuleDescriptor(id) {
var lookupId = id.toLowerCase();
if (!has(modules, lookupId)) {
modules[lookupId] = {
id: id,
display: (config.name || config.location) + "#" + id, // EXTENSION
require: require
};
}
return modules[lookupId];
}
// for preloading modules by their id and exports, useful to
// prevent wasteful multiple instantiation if a module was loaded
// in the bootstrapping process and can be trivially injected into
// the system.
function inject(id, exports) {
var module = getModuleDescriptor(id);
module.exports = exports;
module.location = URL.resolve(config.location, id);
module.directory = URL.resolve(module.location, "./");
module.injected = true;
delete module.redirect;
delete module.mappingRedirect;
}
// Ensures a module definition is loaded, compiled, analyzed
var load = memoize(function (topId, viaId) {
var module = getModuleDescriptor(topId);
return Promise.fcall(function () {
// if not already loaded, already instantiated, or
// configured as a redirection to another module
if (
module.factory === void 0 &&
module.exports === void 0 &&
module.redirect === void 0
) {
return Promise.fcall(config.load, topId, module);
}
})
.then(function () {
// compile and analyze dependencies
config.compile(module);
var dependencies =
module.dependencies =
module.dependencies || [];
if (module.redirect !== void 0) {
dependencies.push(module.redirect);
}
if (module.extraDependencies !== void 0) {
Array.prototype.push.apply(module.dependencies, module.extraDependencies);
}
});
});
// Load a module definition, and the definitions of its transitive
// dependencies
function deepLoad(topId, viaId, loading) {
var module = getModuleDescriptor(topId);
// 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, topId))
return; // break the cycle of violence.
loading[topId] = true; // this has happened before
return load(topId, viaId)
.then(function () {
// load the transitive dependencies using the magic of
// recursion.
return Promise.all(module.dependencies.map(function (depId) {
depId = resolve(depId, topId);
// create dependees set, purely for debug purposes
var module = getModuleDescriptor(depId);
var dependees = module.dependees = module.dependees || {};
dependees[topId] = true;
return deepLoad(depId, topId, loading);
}));
}, function (error) {
module.error = error;
});
}
// Initializes a module by executing the factory function with a new
// module "exports" object.
function getExports(topId, viaId) {
var module = getModuleDescriptor(topId);
// check for consistent case convention
if (module.id !== topId) {
throw new Error(
"Can't require module " + JSON.stringify(module.id) +
" by alternate spelling " + JSON.stringify(topId)
);
}
// check for load error
if (module.error) {
var error = new Error(
"Can't require module " + JSON.stringify(module.id) +
" via " + JSON.stringify(viaId) +
" because " + module.error.message
);
error.cause = module.error;
throw error;
}
// handle redirects
if (module.redirect !== void 0) {
return getExports(module.redirect, viaId);
}
// handle cross-package linkage
if (module.mappingRedirect !== void 0) {
return module.mappingRequire(module.mappingRedirect, viaId);
}
// do not reinitialize modules
if (module.exports !== void 0) {
return module.exports;
}
// 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:
void 0, // this (defaults to global)
makeRequire(topId), // require
module.exports, // exports
module // module
);
// EXTENSION
if (returnValue !== void 0) {
module.exports = returnValue;
}
return module.exports;
}
// Finds the internal identifier for a module in a subpackage
// The `seen` object is a memo of the packages we have seen to avoid
// infinite recursion of cyclic package dependencies. It also 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, seen) {
var location = config.location;
if (require2.location === location)
return id2;
var internal = !!seen;
seen = seen || {};
if (has(seen, location))
return null; // break the cycle of violence.
seen[location] = true;
for (var name in config.mappings) {
var mapping = config.mappings[name];
location = mapping.location;
if (!config.hasPackage(location))
continue;
var candidate = config.getPackage(location);
var id1 = candidate.identify(id2, require2, seen);
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
);
}
}
// Creates a unique require function for each module that encapsulates
// that module's id for resolving relative module IDs against.
function makeRequire(viaId) {
// Main synchronously executing "require()" function
var require = function(id) {
var topId = resolve(id, viaId);
return getExports(topId, viaId);
};
// Asynchronous "require.async()" which ensures async executation
// (even with synchronous loaders)
require.async = function(id) {
var topId = resolve(id, viaId);
var module = getModuleDescriptor(id);
return deepLoad(topId, viaId)
.then(function () {
return require(topId);
});
};
require.resolve = function (id) {
return normalizeId(resolve(id, viaId));
};
require.getModule = getModuleDescriptor; // XXX deprecated, use:
require.getModuleDescriptor = getModuleDescriptor;
require.load = load;
require.deepLoad = deepLoad;
require.loadPackage = function (dependency, givenConfig) {
if (givenConfig) { // explicit configuration, fresh environment
return Require.loadPackage(dependency, givenConfig);
} else { // inherited environment
return config.loadPackage(dependency, config);
}
};
require.hasPackage = function (dependency) {
return config.hasPackage(dependency);
};
require.getPackage = function (dependency) {
return config.getPackage(dependency);
};
require.isMainPackage = function () {
return require.location === config.mainPackageLocation;
};
require.injectPackageDescription = function (location, description) {
Require.injectPackageDescription(location, description, config);
};
require.injectPackageDescriptionLocation = function (location, descriptionLocation) {
Require.injectPackageDescriptionLocation(location, descriptionLocation, config);
};
require.injectMapping = function (dependency, name) {
dependency = normalizeDependency(dependency, config, name);
name = name || dependency.name;
config.mappings[name] = dependency;
};
require.injectDependency = function (name) {
require.injectMapping({name: name}, name);
};
require.identify = identify;
require.inject = inject;
config.exposedConfigs.forEach(function(name) {
require[name] = config[name];
});
require.config = config;
require.read = Require.read;
return require;
}
require = makeRequire("");
return require;
};
Require.injectPackageDescription = function (location, description, config) {
var descriptions =
config.descriptions =
config.descriptions || {};
descriptions[location] = Promise.resolve(description);
};
Require.injectPackageDescriptionLocation = function (location, descriptionLocation, config) {
var descriptionLocations =
config.descriptionLocations =
config.descriptionLocations || {};
descriptionLocations[location] = descriptionLocation;
};
Require.loadPackageDescription = function (dependency, config) {
var location = dependency.location;
var descriptions =
config.descriptions =
config.descriptions || {};
if (descriptions[location] === void 0) {
var descriptionLocations =
config.descriptionLocations =
config.descriptionLocations || {};
var descriptionLocation;
if (descriptionLocations[location]) {
descriptionLocation = descriptionLocations[location];
} else {
descriptionLocation = URL.resolve(location, "package.json");
}
descriptions[location] = Require.read(descriptionLocation)
.then(function (json) {
try {
return JSON.parse(json);
} catch (error) {
error.message = error.message + " in " + JSON.stringify(descriptionLocation)
throw error;
}
});
}
return descriptions[location];
};
Require.loadPackage = function (dependency, config) {
dependency = normalizeDependency(dependency, config);
if (!dependency.location) {
throw new Error("Can't find dependency: " + JSON.stringify(dependency));
}
var location = dependency.location;
config = Object.create(config || null);
var loadingPackages = config.loadingPackages = config.loadingPackages || {};
var loadedPackages = config.packages = {};
var registry = config.registry = config.registry || Object.create(null);
config.mainPackageLocation = location;
config.hasPackage = function (dependency) {
dependency = normalizeDependency(dependency, config);
if (!dependency.location)
return false;
var location = dependency.location;
return !!loadedPackages[location];
};
config.getPackage = function (dependency) {
dependency = normalizeDependency(dependency, config);
if (!dependency.location) {
throw new Error("Can't find dependency: " + JSON.stringify(dependency) + " from " + config.location);
}
var location = dependency.location;
if (!loadedPackages[location]) {
if (loadingPackages[location]) {
throw new Error(
"Dependency has not finished loading: " + JSON.stringify(dependency)
);
} else {
throw new Error(
"Dependency was not loaded: " + JSON.stringify(dependency)
);
}
}
return loadedPackages[location];
};
config.loadPackage = function (dependency, viaConfig) {
dependency = normalizeDependency(dependency, viaConfig);
if (!dependency.location) {
throw new Error("Can't find dependency: " + JSON.stringify(dependency) + " from " + config.location);
}
var location = dependency.location;
if (!loadingPackages[location]) {
loadingPackages[location] = Require.loadPackageDescription(dependency, config)
.then(function (packageDescription) {
var subconfig = configurePackage(
location,
packageDescription,
config
);
var pkg = Require.makeRequire(subconfig);
loadedPackages[location] = pkg;
return pkg;
});
}
return loadingPackages[location];
};
var pkg = config.loadPackage(dependency);
pkg.location = location;
pkg.async = function (id, callback) {
return pkg.then(function (require) {
return require.async(id, callback);
});
};
return pkg;
};
function normalizeDependency(dependency, config, name) {
config = config || {};
if (typeof dependency === "string") {
dependency = {
location: dependency
};
}
if (dependency.main) {
dependency.location = config.mainPackageLocation;
}
// if the named dependency has already been found at another
// location, refer to the same eventual instance
if (
dependency.name &&
config.registry &&
config.registry[dependency.name]
) {
dependency.location = config.registry[dependency.name];
}
// default location
if (!dependency.location && config.packagesDirectory && dependency.name) {
dependency.location = URL.resolve(
config.packagesDirectory,
dependency.name + "/"
);
}
if (!dependency.location)
return dependency; // partially completed
// make sure the dependency location has a trailing slash so that
// relative urls will resolve properly
if (!/\/$/.test(depen