[Pkg-javascript-commits] [require-kernel.js] 01/04: Imported Upstream version 1.0.6
Mike Gabriel
sunweaver at debian.org
Thu Dec 15 10:40:29 UTC 2016
This is an automated email from the git hooks/post-receive script.
sunweaver pushed a commit to branch master
in repository require-kernel.js.
commit c758c87adb59b97660e81e63f437fc27c3772c53
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date: Tue May 28 00:13:06 2013 +0200
Imported Upstream version 1.0.6
---
README.md | 39 ++
index.js | 13 +
kernel.js | 708 ++++++++++++++++++++++++++++++++
mock_require.js | 271 ++++++++++++
package.json | 17 +
test/modules/index/index.js | 1 +
test/modules/index/index/index.js | 1 +
test/modules/index/index/index/index.js | 1 +
test/modules/library/1.js | 1 +
test/modules/root/1.js | 1 +
test/modules/root/order/1.js | 4 +
test/modules/root/order/2.js | 5 +
test/modules/root/order/3.js | 5 +
test/modules/root/order/4.js | 5 +
test/modules/root/order/5.js | 4 +
test/modules/root/order/6.js | 2 +
test/modules/root/order/7.js | 4 +
test/modules/root/order/8.js | 2 +
test/modules/root/order/index.js | 0
test/modules/root/spa ce s.js | 1 +
test/test.js | 206 ++++++++++
21 files changed, 1291 insertions(+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..44769dd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+# require-kernel #
+
+This is an implementation of the [CommonJS module standard](http://wiki.commonjs.org/wiki/Modules/1.1) for a browser environment.
+
+## Usage ##
+
+The kernel is a code fragment that evaluates to an unnamed function.
+
+### Interface ###
+
+Modules can be loaded either synchronously and asynchronously:
+
+* `module = require(path)`
+* `require(path1[, path2[, ...]], function (module1[, module2[, ...]]) {})`
+
+The kernel has the following methods:
+
+* `define`: A method for defining modules. It may be invoked one of several ways. In either case the path is expected to be fully qualified and the module a function with the signature `(require, exports, module)`.
+ * `require.define(path, module)`
+ * `require.define({path1: module1[, path2: module2[, ...]]})`
+* `setGlobalKeyPath`: A string (such as `"require"` and `"namespace.req"`) that evaluates to the kernel in the global scope. Asynchronous retrieval of modules using JSONP will happen if and only if this path is defined. Default is `undefined`.
+* `setRootURI`: The URI that non-library paths will be requested relative to. Default is `undefined`.
+* `setLibraryURI`: The URI that library paths (i.e. paths that do not match `/^\.{0,2}\//`) will be requested relative to. Default is `undefined`.
+* `setRequestMaximum`: The maximum number of concurrent requests. Default is `2`.
+* `setLibraryLookupComponent`: A string (such as `"node_modules"`). If defined, libraries will be searched for in parent directories. Default is `undefined`.
+
+## Behavior ##
+
+### JSONP ###
+
+If a global key path was set for the kernel and the request is allowed to be asynchronous, a JSONP will be used to request the module. The callback parameter sent in the request is the `define` method of `require` (as specified by the global key path).
+
+### Cross Origin Resources ###
+
+JSONP accomplishes CORS, so if such a request is possible to make, it is made, else, if the user agent is capable of such a request, requests to cross origin resources can be made, if not (IE[6,7]), the kernel will attempt to make a request to a mirrored location on the same origin (`http://static.example.com/javascripts/index.js` becomes `http://www.example.com/javascripts/index.js`).
+
+## License ##
+
+Released to the public domain. In any regions where transfer the public domain is not possible the software is granted under the terms of the MIT License.
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..41473ca
--- /dev/null
+++ b/index.js
@@ -0,0 +1,13 @@
+/*!
+
+ require-kernel
+
+ Created by Chad Weider on 01/04/11.
+ Released to the Public Domain on 17/01/12.
+
+*/
+
+var MockRequire = require('./mock_require');
+
+exports.kernelSource = MockRequire.kernelSource;
+exports.requireForPaths = MockRequire.requireForPaths;
diff --git a/kernel.js b/kernel.js
new file mode 100644
index 0000000..dde52dc
--- /dev/null
+++ b/kernel.js
@@ -0,0 +1,708 @@
+(function () {
+/*!
+
+ require-kernel
+
+ Created by Chad Weider on 01/04/11.
+ Released to the Public Domain on 17/01/12.
+
+*/
+
+ /* Storage */
+ var main = null; // Reference to main module in `modules`.
+ var modules = {}; // Repository of module objects build from `definitions`.
+ var definitions = {}; // Functions that construct `modules`.
+ var loadingModules = {}; // Locks for detecting circular dependencies.
+ var definitionWaiters = {}; // Locks for clearing duplicate requires.
+ var fetchRequests = []; // Queue of pending requests.
+ var currentRequests = 0; // Synchronization for parallel requests.
+ var maximumRequests = 2; // The maximum number of parallel requests.
+ var deferred = []; // A list of callbacks that can be evaluated eventually.
+ var deferredScheduled = false; // If deferred functions will be executed.
+
+ var syncLock = undefined;
+ var globalKeyPath = undefined;
+
+ var rootURI = undefined;
+ var libraryURI = undefined;
+
+ var libraryLookupComponent = undefined;
+
+ var JSONP_TIMEOUT = 60 * 1000;
+
+ function CircularDependencyError(message) {
+ this.name = "CircularDependencyError";
+ this.message = message;
+ };
+ CircularDependencyError.prototype = Error.prototype;
+ function ArgumentError(message) {
+ this.name = "ArgumentError";
+ this.message = message;
+ };
+ ArgumentError.prototype = Error.prototype;
+
+ /* Utility */
+ function hasOwnProperty(object, key) {
+ // Object-independent because an object may define `hasOwnProperty`.
+ return Object.prototype.hasOwnProperty.call(object, key);
+ }
+
+ /* Deferral */
+ function defer(f_1, f_2, f_n) {
+ deferred.push.apply(deferred, arguments);
+ }
+
+ function _flushDefer() {
+ // Let exceptions happen, but don't allow them to break notification.
+ try {
+ while (deferred.length) {
+ var continuation = deferred.shift();
+ continuation();
+ }
+ deferredScheduled = false;
+ } finally {
+ deferredScheduled = deferred.length > 0;
+ deferred.length && setTimeout(_flushDefer, 0);
+ }
+ }
+
+ function flushDefer() {
+ if (!deferredScheduled && deferred.length > 0) {
+ if (syncLock) {
+ // Only asynchronous operations will wait on this condition so schedule
+ // and don't interfere with the synchronous operation in progress.
+ deferredScheduled = true;
+ setTimeout(_flushDefer, 0);
+ } else {
+ _flushDefer();
+ }
+ }
+ }
+
+ function flushDeferAfter(f) {
+ try {
+ deferredScheduled = true;
+ f();
+ deferredScheduled = false;
+ flushDefer();
+ } finally {
+ deferredScheduled = false;
+ deferred.length && setTimeout(flushDefer, 0);
+ }
+ }
+
+ // See RFC 2396 Appendix B
+ var URI_EXPRESSION =
+ /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
+ function parseURI(uri) {
+ var match = uri.match(URI_EXPRESSION);
+ var location = match && {
+ scheme: match[2],
+ host: match[4],
+ path: match[5],
+ query: match[7],
+ fragment: match[9]
+ };
+ return location;
+ }
+
+ function joinURI(location) {
+ var uri = "";
+ if (location.scheme)
+ uri += location.scheme + ':';
+ if (location.host)
+ uri += "//" + location.host
+ if (location.host && location.path && location.path.charAt(0) != '/')
+ url += "/"
+ if (location.path)
+ uri += location.path
+ if (location.query)
+ uri += "?" + location.query
+ if (uri.fragment)
+ uri += "#" + location.fragment
+
+ return uri;
+ }
+
+ function isSameDomain(uri) {
+ var host_uri =
+ (typeof location == "undefined") ? {} : parseURI(location.toString());
+ var uri = parseURI(uri);
+
+ return (!uri.scheme && !uri.host)
+ || (uri.scheme === host_uri.scheme) && (uri.host === host_uri.host);
+ }
+
+ function mirroredURIForURI(uri) {
+ var host_uri =
+ (typeof location == "undefined") ? {} : parseURI(location.toString());
+ var uri = parseURI(uri);
+
+ uri.scheme = host_uri.scheme;
+ uri.host = host_uri.host;
+ return joinURI(uri);
+ }
+
+ function normalizePath(path) {
+ var pathComponents1 = path.split('/');
+ var pathComponents2 = [];
+
+ var component;
+ for (var i = 0, ii = pathComponents1.length; i < ii; i++) {
+ component = pathComponents1[i];
+ switch (component) {
+ case '':
+ if (i == 0 || i == ii - 1) {
+ // This indicates a leading or trailing slash.
+ pathComponents2.push(component);
+ }
+ break;
+ case '.':
+ // Always skip.
+ break;
+ case '..':
+ if (pathComponents2.length > 1
+ || (pathComponents2.length == 1
+ && pathComponents2[0] != ''
+ && pathComponents2[0] != '.')) {
+ pathComponents2.pop();
+ break;
+ }
+ default:
+ pathComponents2.push(component);
+ }
+ }
+
+ return pathComponents2.join('/');
+ }
+
+ function fullyQualifyPath(path, basePath) {
+ var fullyQualifiedPath = path;
+ if (path.charAt(0) == '.'
+ && (path.charAt(1) == '/'
+ || (path.charAt(1) == '.' && path.charAt(2) == '/'))) {
+ if (!basePath) {
+ basePath = '';
+ } else if (basePath.charAt(basePath.length-1) != '/') {
+ basePath += '/';
+ }
+ fullyQualifiedPath = basePath + path;
+ }
+ return fullyQualifiedPath;
+ }
+
+ function setRootURI(URI) {
+ if (!URI) {
+ throw new ArgumentError("Invalid root URI.");
+ }
+ rootURI = (URI.charAt(URI.length-1) == '/' ? URI.slice(0,-1) : URI);
+ }
+
+ function setLibraryURI(URI) {
+ libraryURI = (URI.charAt(URI.length-1) == '/' ? URI : URI + '/');
+ }
+
+ function setLibraryLookupComponent(component) {
+ component = component && component.toString();
+ if (!component) {
+ libraryLookupComponent = undefined;
+ } else if (component.match(/\//)) {
+ throw new ArgumentError("Invalid path component.");
+ } else {
+ libraryLookupComponent = component;
+ }
+ }
+
+ // If a `libraryLookupComponent` is defined, then library modules should
+ // be looked at in every parent directory (roughly).
+ function searchPathsForModulePath(path, basePath) {
+ path = normalizePath(path);
+
+ // Should look for nearby libarary modules.
+ if (path.charAt(0) != '/' && libraryLookupComponent) {
+ var paths = [];
+ var components = basePath.split('/');
+
+ while (components.length > 1) {
+ if (components[components.length-1] == libraryLookupComponent) {
+ components.pop();
+ }
+ var searchPath = normalizePath(fullyQualifyPath(
+ './'+libraryLookupComponent+'/' + path, components.join('/') + '/'
+ ));
+ paths.push(searchPath);
+ components.pop();
+ }
+ paths.push(path);
+ return paths;
+ } else {
+ return [normalizePath(fullyQualifyPath(path, basePath))];
+ }
+ }
+
+ function URIForModulePath(path) {
+ var components = path.split('/');
+ for (var i = 0, ii = components.length; i < ii; i++) {
+ components[i] = encodeURIComponent(components[i]);
+ }
+ path = components.join('/')
+
+ if (path.charAt(0) == '/') {
+ if (!rootURI) {
+ throw new Error("Attempt to retrieve the root module "
+ + "\""+ path + "\" but no root URI is defined.");
+ }
+ return rootURI + path;
+ } else {
+ if (!libraryURI) {
+ throw new Error("Attempt to retrieve the library module "
+ + "\""+ path + "\" but no libary URI is defined.");
+ }
+ return libraryURI + path;
+ }
+ }
+
+ function _compileFunction(code, filename) {
+ return new Function(code);
+ }
+
+ function compileFunction(code, filename) {
+ var compileFunction = rootRequire._compileFunction || _compileFunction;
+ return compileFunction.apply(this, arguments);
+ }
+
+ /* Remote */
+ function setRequestMaximum (value) {
+ value == parseInt(value);
+ if (value > 0) {
+ maximumRequests = value;
+ checkScheduledfetchDefines();
+ } else {
+ throw new ArgumentError("Value must be a positive integer.")
+ }
+ }
+
+ function setGlobalKeyPath (value) {
+ globalKeyPath = value;
+ }
+
+ var XMLHttpFactories = [
+ function () {return new XMLHttpRequest()},
+ function () {return new ActiveXObject("Msxml2.XMLHTTP")},
+ function () {return new ActiveXObject("Msxml3.XMLHTTP")},
+ function () {return new ActiveXObject("Microsoft.XMLHTTP")}
+ ];
+
+ function createXMLHTTPObject() {
+ var xmlhttp = false;
+ for (var i = 0, ii = XMLHttpFactories.length; i < ii; i++) {
+ try {
+ xmlhttp = XMLHttpFactories[i]();
+ } catch (error) {
+ continue;
+ }
+ break;
+ }
+ return xmlhttp;
+ }
+
+ function getXHR(uri, async, callback, request) {
+ var request = request || createXMLHTTPObject();
+ if (!request) {
+ throw new Error("Error making remote request.")
+ }
+
+ function onComplete(request) {
+ // Build module constructor.
+ if (request.status == 200) {
+ callback(undefined, request.responseText);
+ } else {
+ callback(true, undefined);
+ }
+ }
+
+ request.open('GET', uri, !!(async));
+ if (async) {
+ request.onreadystatechange = function (event) {
+ if (request.readyState == 4) {
+ onComplete(request);
+ }
+ };
+ request.send(null);
+ } else {
+ request.send(null);
+ onComplete(request);
+ }
+ }
+
+ function getXDR(uri, callback) {
+ var xdr = new XDomainRequest();
+ xdr.open('GET', uri);
+ xdr.error(function () {
+ callback(true, undefined);
+ });
+ xdr.onload(function () {
+ callback(undefined, request.responseText);
+ });
+ xdr.send();
+ }
+
+ function fetchDefineXHR(path, async) {
+ // If cross domain and request doesn't support such requests, go straight
+ // to mirroring.
+
+ var _globalKeyPath = globalKeyPath;
+
+ var callback = function (error, text) {
+ if (error) {
+ define(path, null);
+ } else {
+ if (_globalKeyPath) {
+ compileFunction(text, path)();
+ } else {
+ var definition = compileFunction(
+ 'return (function (require, exports, module) {'
+ + text + '\n'
+ + '})', path)();
+ define(path, definition);
+ }
+ }
+ }
+
+ var uri = URIForModulePath(path);
+ if (_globalKeyPath) {
+ uri += '?callback=' + encodeURIComponent(globalKeyPath + '.define');
+ }
+ if (isSameDomain(uri)) {
+ getXHR(uri, async, callback);
+ } else {
+ var request = createXMLHTTPObject();
+ if (request && request.withCredentials !== undefined) {
+ getXHR(uri, async, callback, request);
+ } else if (async && (typeof XDomainRequest != "undefined")) {
+ getXDR(uri, callback);
+ } else {
+ getXHR(mirroredURIForURI(uri), async, callback);
+ }
+ }
+ }
+
+ function fetchDefineJSONP(path) {
+ var head = document.head
+ || document.getElementsByTagName('head')[0]
+ || document.documentElement;
+ var script = document.createElement('script');
+ if (script.async !== undefined) {
+ script.async = "true";
+ } else {
+ script.defer = "true";
+ }
+ script.type = "application/javascript";
+ script.src = URIForModulePath(path)
+ + '?callback=' + encodeURIComponent(globalKeyPath + '.define');
+
+ // Handle failure of JSONP request.
+ if (JSONP_TIMEOUT < Infinity) {
+ var timeoutId = setTimeout(function () {
+ timeoutId = undefined;
+ define(path, null);
+ }, JSONP_TIMEOUT);
+ definitionWaiters[path].unshift(function () {
+ timeoutId === undefined && clearTimeout(timeoutId);
+ });
+ }
+
+ head.insertBefore(script, head.firstChild);
+ }
+
+ /* Modules */
+ function fetchModule(path, continuation) {
+ if (hasOwnProperty(definitionWaiters, path)) {
+ definitionWaiters[path].push(continuation);
+ } else {
+ definitionWaiters[path] = [continuation];
+ schedulefetchDefine(path);
+ }
+ }
+
+ function schedulefetchDefine(path) {
+ fetchRequests.push(path);
+ checkScheduledfetchDefines();
+ }
+
+ function checkScheduledfetchDefines() {
+ if (fetchRequests.length > 0 && currentRequests < maximumRequests) {
+ var fetchRequest = fetchRequests.pop();
+ currentRequests++;
+ definitionWaiters[fetchRequest].unshift(function () {
+ currentRequests--;
+ checkScheduledfetchDefines();
+ });
+ if (globalKeyPath
+ && typeof document !== 'undefined'
+ && document.readyState
+ && /^loaded|complete$/.test(document.readyState)) {
+ fetchDefineJSONP(fetchRequest);
+ } else {
+ fetchDefineXHR(fetchRequest, true);
+ }
+ }
+ }
+
+ function fetchModuleSync(path, continuation) {
+ fetchDefineXHR(path, false);
+ continuation();
+ }
+
+ function moduleIsLoaded(path) {
+ return hasOwnProperty(modules, path);
+ }
+
+ function loadModule(path, continuation) {
+ // If it's a function then it hasn't been exported yet. Run function and
+ // then replace with exports result.
+ if (!moduleIsLoaded(path)) {
+ if (hasOwnProperty(loadingModules, path)) {
+ throw new CircularDependencyError("Encountered circular dependency.");
+ } else if (!moduleIsDefined(path)) {
+ throw new Error("Attempt to load undefined module.");
+ } else if (definitions[path] === null) {
+ continuation(null);
+ } else {
+ var definition = definitions[path];
+ var _module = {id: path, exports: {}};
+ var _require = requireRelativeTo(path);
+ if (!main) {
+ main = _module;
+ }
+ try {
+ loadingModules[path] = true;
+ definition(_require, _module.exports, _module);
+ modules[path] = _module;
+ delete loadingModules[path];
+ continuation(_module);
+ } finally {
+ delete loadingModules[path];
+ }
+ }
+ } else {
+ var module = modules[path];
+ continuation(module);
+ }
+ }
+
+ function _moduleAtPath(path, fetchFunc, continuation) {
+ var suffixes = ['', '.js', '/index.js'];
+ if (path.charAt(path.length - 1) == '/') {
+ suffixes = ['index.js'];
+ }
+
+ var i = 0, ii = suffixes.length;
+ var _find = function (i) {
+ if (i < ii) {
+ var path_ = path + suffixes[i];
+ var after = function () {
+ loadModule(path_, function (module) {
+ if (module === null) {
+ _find(i + 1);
+ } else {
+ continuation(module);
+ }
+ });
+ }
+
+ if (!moduleIsDefined(path_)) {
+ fetchFunc(path_, after);
+ } else {
+ after();
+ }
+
+ } else {
+ continuation(null);
+ }
+ };
+ _find(0);
+ }
+
+ function moduleAtPath(path, continuation) {
+ defer(function () {
+ _moduleAtPath(path, fetchModule, continuation);
+ });
+ }
+
+ function moduleAtPathSync(path) {
+ var module;
+ var oldSyncLock = syncLock;
+ syncLock = true;
+ try {
+ _moduleAtPath(path, fetchModuleSync, function (_module) {
+ module = _module;
+ });
+ } finally {
+ syncLock = oldSyncLock;
+ }
+ return module;
+ }
+
+ /* Definition */
+ function moduleIsDefined(path) {
+ return hasOwnProperty(definitions, path);
+ }
+
+ function defineModule(path, module) {
+ if (typeof path != 'string'
+ || !((typeof module == 'function') || module === null)) {
+ throw new ArgumentError(
+ "Definition must be a (string, function) pair.");
+ }
+
+ if (moduleIsDefined(path)) {
+ // Drop import silently
+ } else {
+ definitions[path] = module;
+ }
+ }
+
+ function defineModules(moduleMap) {
+ if (typeof moduleMap != 'object') {
+ throw new ArgumentError("Mapping must be an object.");
+ }
+ for (var path in moduleMap) {
+ if (hasOwnProperty(moduleMap, path)) {
+ defineModule(path, moduleMap[path]);
+ }
+ }
+ }
+
+ function define(fullyQualifiedPathOrModuleMap, module) {
+ var moduleMap;
+ if (arguments.length == 1) {
+ moduleMap = fullyQualifiedPathOrModuleMap;
+ defineModules(moduleMap);
+ } else if (arguments.length == 2) {
+ var path = fullyQualifiedPathOrModuleMap;
+ defineModule(fullyQualifiedPathOrModuleMap, module);
+ moduleMap = {};
+ moduleMap[path] = module;
+ } else {
+ throw new ArgumentError("Expected 1 or 2 arguments, but got "
+ + arguments.length + ".");
+ }
+
+ // With all modules installed satisfy those conditions for all waiters.
+ for (var path in moduleMap) {
+ if (hasOwnProperty(moduleMap, path)
+ && hasOwnProperty(definitionWaiters, path)) {
+ defer.apply(this, definitionWaiters[path]);
+ delete definitionWaiters[path];
+ }
+ }
+
+ flushDefer();
+ }
+
+ /* Require */
+ function _designatedRequire(path, continuation, relativeTo) {
+ var paths = searchPathsForModulePath(path, relativeTo);
+
+ if (continuation === undefined) {
+ var module;
+ for (var i = 0, ii = paths.length; i < ii && !module; i++) {
+ var path = paths[i];
+ module = moduleAtPathSync(path);
+ }
+ if (!module) {
+ throw new Error("The module at \"" + path + "\" does not exist.");
+ }
+ return module.exports;
+ } else {
+ if (!(typeof continuation == 'function')) {
+ throw new ArgumentError("Continuation must be a function.");
+ }
+
+ flushDeferAfter(function () {
+ function search() {
+ var path = paths.shift();
+ return moduleAtPath(path, function (module) {
+ if (module || paths.length == 0) {
+ continuation(module && module.exports);
+ } else {
+ search();
+ }
+ })
+ }
+ search();
+ });
+ }
+ }
+
+ function designatedRequire(path, continuation) {
+ var designatedRequire =
+ rootRequire._designatedRequire || _designatedRequire;
+ return designatedRequire.apply(this, arguments);
+ }
+
+ function requireRelative(basePath, qualifiedPath, continuation) {
+ qualifiedPath = qualifiedPath.toString();
+ var path = normalizePath(fullyQualifyPath(qualifiedPath, basePath));
+ return designatedRequire(path, continuation, basePath);
+ }
+
+ function requireRelativeN(basePath, qualifiedPaths, continuation) {
+ if (!(typeof continuation == 'function')) {
+ throw new ArgumentError("Final argument must be a continuation.");
+ } else {
+ // Copy and validate parameters
+ var _qualifiedPaths = [];
+ for (var i = 0, ii = qualifiedPaths.length; i < ii; i++) {
+ _qualifiedPaths[i] = qualifiedPaths[i].toString();
+ }
+ var results = [];
+ function _require(result) {
+ results.push(result);
+ if (qualifiedPaths.length > 0) {
+ requireRelative(basePath, qualifiedPaths.shift(), _require);
+ } else {
+ continuation.apply(this, results);
+ }
+ }
+ for (var i = 0, ii = qualifiedPaths.length; i < ii; i++) {
+ requireRelative(basePath, _qualifiedPaths[i], _require);
+ }
+ }
+ }
+
+ var requireRelativeTo = function (basePath) {
+ basePath = basePath.replace(/[^\/]+$/, '');
+ function require(qualifiedPath, continuation) {
+ if (arguments.length > 2) {
+ var qualifiedPaths = Array.prototype.slice.call(arguments, 0, -1);
+ var continuation = arguments[arguments.length-1];
+ return requireRelativeN(basePath, qualifiedPaths, continuation);
+ } else {
+ return requireRelative(basePath, qualifiedPath, continuation);
+ }
+ }
+ require.main = main;
+
+ return require;
+ }
+
+ var rootRequire = requireRelativeTo('/');
+
+ /* Private internals */
+ rootRequire._modules = modules;
+ rootRequire._definitions = definitions;
+ rootRequire._designatedRequire = _designatedRequire;
+ rootRequire._compileFunction = _compileFunction;
+
+ /* Public interface */
+ rootRequire.define = define;
+ rootRequire.setRequestMaximum = setRequestMaximum;
+ rootRequire.setGlobalKeyPath = setGlobalKeyPath;
+ rootRequire.setRootURI = setRootURI;
+ rootRequire.setLibraryURI = setLibraryURI;
+ rootRequire.setLibraryLookupComponent = setLibraryLookupComponent;
+
+ return rootRequire;
+}())
\ No newline at end of file
diff --git a/mock_require.js b/mock_require.js
new file mode 100644
index 0000000..5b2d913
--- /dev/null
+++ b/mock_require.js
@@ -0,0 +1,271 @@
+/*!
+
+ require-kernel
+
+ Created by Chad Weider on 01/04/11.
+ Released to the Public Domain on 17/01/12.
+
+*/
+
+var fs = require('fs');
+var pathutil = require('path');
+var urlutil = require('url');
+var events = require('events');
+
+var kernelPath = pathutil.join(__dirname, 'kernel.js');
+var kernel = fs.readFileSync(kernelPath, 'utf8');
+
+var buildKernel = require('vm').runInThisContext(
+ '(function (XMLHttpRequest) {return ' + kernel + '})', kernelPath);
+
+/* Cheap URL request implementation */
+var fs_client = (new function () {
+ var STATUS_MESSAGES = {
+ 403: '403: Access denied.'
+ , 404: '404: File not found.'
+ , 405: '405: Only the HEAD or GET methods are allowed.'
+ , 500: '500: Error reading file.'
+ };
+
+ function request(options, callback) {
+ var path = fsPathForURIPath(options.path);
+ var method = options.method;
+
+ var response = new (require('events').EventEmitter);
+ response.setEncoding = function (encoding) {this._encoding = encoding};
+ response.statusCode = 504;
+ response.headers = {};
+
+ var request = new (require('events').EventEmitter);
+ request.end = function () {
+ if (options.method != 'HEAD' && options.method != 'GET') {
+ response.statusCode = 405;
+ response.headers['Allow'] = 'HEAD, GET';
+
+ callback(response);
+ response.emit('data', STATUS_MESSAGES[response.statusCode])
+ response.emit('end');
+ } else {
+ fs.stat(path, function (error, stats) {
+ if (error) {
+ if (error.code == 'ENOENT') {
+ response.StatusCode = 404;
+ } else if (error.code == 'EACCESS') {
+ response.StatusCode = 403;
+ } else {
+ response.StatusCode = 502;
+ }
+ } else if (stats.isFile()) {
+ var date = new Date()
+ var modifiedLast = new Date(stats.mtime);
+ var modifiedSince = (options.headers || {})['if-modified-since'];
+
+ response.headers['Date'] = date.toUTCString();
+ response.headers['Last-Modified'] = modifiedLast.toUTCString();
+
+ if (modifiedSince && modifiedLast
+ && modifiedSince >= modifiedLast) {
+ response.StatusCode = 304;
+ } else {
+ response.statusCode = 200;
+ }
+ } else {
+ response.StatusCode = 404;
+ }
+
+ if (method == 'HEAD') {
+ callback(response);
+ response.emit('end');
+ } else if (response.statusCode != 200) {
+ response.headers['Content-Type'] = 'text/plain; charset=utf-8';
+
+ callback(response);
+ response.emit('data', STATUS_MESSAGES[response.statusCode])
+ response.emit('end');
+ } else {
+ fs.readFile(path, function (error, text) {
+ if (error) {
+ if (error.code == 'ENOENT') {
+ response.statusCode = 404;
+ } else if (error.code == 'EACCESS') {
+ response.statusCode = 403;
+ } else {
+ response.statusCode = 502;
+ }
+ response.headers['Content-Type'] = 'text/plain; charset=utf-8';
+
+ callback(response);
+ response.emit('data', STATUS_MESSAGES[response.statusCode])
+ response.emit('end');
+ } else {
+ response.statusCode = 200;
+ response.headers['Content-Type'] =
+ 'application/javascript; charset=utf-8';
+
+ callback(response);
+ response.emit('data', text);
+ response.emit('end');
+ }
+ });
+ }
+ });
+ }
+ };
+ return request;
+ }
+ this.request = request;
+}());
+
+function requestURL(url, method, headers, callback) {
+ var parsedURL = urlutil.parse(url);
+ var client = undefined;
+ if (parsedURL.protocol == 'file:') {
+ client = fs_client;
+ } else if (parsedURL.protocol == 'http:') {
+ client = require('http');
+ } else if (parsedURL.protocol == 'https:') {
+ client = require('https');
+ }
+ if (client) {
+ var request = client.request({
+ host: parsedURL.host
+ , port: parsedURL.port
+ , path: parsedURL.path
+ , method: method
+ , headers: headers
+ }, function (response) {
+ var buffer = undefined;
+ response.setEncoding('utf8');
+ response.on('data', function (chunk) {
+ buffer = buffer || '';
+ buffer += chunk;
+ });
+ response.on('close', function () {
+ callback(502, {});
+ });
+ response.on('end', function () {
+ callback(response.statusCode, response.headers, buffer);
+ });
+ });
+ request.on('error', function () {
+ callback(502, {});
+ });
+ request.end();
+ }
+}
+
+function fsPathForURIPath(path) {
+ path = decodeURIComponent(path);
+ if (path.charAt(0) == '/') { // Account for '/C:\Windows' type of paths.
+ path = pathutil.resolve('/', path.slice(1));
+ }
+ path = pathutil.normalize(path);
+ return path;
+}
+
+function normalizePathAsURI(path) {
+ var parsedUrl = urlutil.parse(path);
+ if (parsedUrl.protocol === undefined) {
+ parsedUrl.protocol = 'file:';
+ parsedUrl.path = pathutil.resolve(parsedUrl.path);
+ }
+ return urlutil.format(parsedUrl);
+}
+
+var buildMockXMLHttpRequestClass = function () {
+ var emitter = new events.EventEmitter();
+ var requestCount = 0;
+ var idleTimer = undefined;
+ var idleHandler = function () {
+ emitter.emit('idle');
+ };
+ var requested = function (info) {
+ clearTimeout(idleTimer);
+ requestCount++;
+ emitter.emit('requested', info);
+ };
+ var responded = function (info) {
+ emitter.emit('responded', info);
+ requestCount--;
+ if (requestCount == 0) {
+ idleTimer = setTimeout(idleHandler, 0);
+ }
+ };
+
+ var MockXMLHttpRequest = function () {
+ };
+ MockXMLHttpRequest.prototype = new function () {
+ this.open = function(method, url, async) {
+ this.async = async;
+ this.url = normalizePathAsURI(url);
+ }
+ this.withCredentials = false; // Pass CORS capability checks.
+ this.send = function () {
+ var parsedURL = urlutil.parse(this.url);
+
+ var info = {
+ async: !!this.async
+ , url: this.url
+ };
+
+ if (!this.async) {
+ if (parsedURL.protocol == 'file:') {
+ requested(info);
+ try {
+ this.status = 200;
+ var path = fsPathForURIPath(parsedURL.pathname);
+ this.responseText = fs.readFileSync(path);
+ } catch (e) {
+ this.status = 404;
+ }
+ this.readyState = 4;
+ responded(info);
+ } else {
+ throw "The resource at " + JSON.stringify(this.url)
+ + " cannot be retrieved synchronously.";
+ }
+ } else {
+ var self = this;
+ requestURL(this.url, 'GET', {},
+ function (status, headers, content) {
+ self.status = status;
+ self.responseText = content;
+ self.readyState = 4;
+ var handler = self.onreadystatechange;
+ handler && handler();
+ responded(info);
+ }
+ );
+ requested(info);
+ }
+ }
+ };
+ MockXMLHttpRequest.emitter = emitter;
+
+ return MockXMLHttpRequest;
+}
+
+function requireForPaths(rootPath, libraryPath) {
+ var MockXMLHttpRequest = buildMockXMLHttpRequestClass();
+ var mockRequire = buildKernel(MockXMLHttpRequest);
+
+ if (rootPath !== undefined) {
+ mockRequire.setRootURI(normalizePathAsURI(rootPath));
+ }
+ if (libraryPath != undefined) {
+ mockRequire.setLibraryURI(normalizePathAsURI(libraryPath));
+ }
+
+ mockRequire.emitter = MockXMLHttpRequest.emitter;
+
+ mockRequire._compileFunction = function (code, filename) {
+ return require('vm').runInThisContext('(function () {'
+ + code + '\n'
+ + '})', filename);
+ };
+
+ return mockRequire;
+}
+
+exports.kernelSource = kernel;
+exports.requireForPaths = requireForPaths;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..cef59dd
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "require-kernel"
+, "description": "A reference implementation of a CommonJS module loader."
+, "homepage": "https://github.com/cweider/require-kernel"
+, "keywords": ["commonjs", "require", "loader", "editor"]
+, "author": {
+ "name": "Chad Weider"
+ , "email": "cweider at oofn.net"
+ , "url": "http://oofn.net"
+ }
+, "dependencies": {}
+, "version": "1.0.6"
+, "repository": {
+ "type": "git"
+ , "url": "git://github.com/cweider/require-kernel"
+ }
+}
diff --git a/test/modules/index/index.js b/test/modules/index/index.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/index/index.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/modules/index/index/index.js b/test/modules/index/index/index.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/index/index/index.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/modules/index/index/index/index.js b/test/modules/index/index/index/index.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/index/index/index/index.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/modules/library/1.js b/test/modules/library/1.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/library/1.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/modules/root/1.js b/test/modules/root/1.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/root/1.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/modules/root/order/1.js b/test/modules/root/order/1.js
new file mode 100644
index 0000000..7e7503a
--- /dev/null
+++ b/test/modules/root/order/1.js
@@ -0,0 +1,4 @@
+require('./2', './3', './4', function () {});
+
+exports.value = 1;
+satisfyModule(1)
diff --git a/test/modules/root/order/2.js b/test/modules/root/order/2.js
new file mode 100644
index 0000000..6e5533a
--- /dev/null
+++ b/test/modules/root/order/2.js
@@ -0,0 +1,5 @@
+require('./5', function () {});
+require('./6', function () {});
+
+exports.value = 2;
+satisfyModule(2);
diff --git a/test/modules/root/order/3.js b/test/modules/root/order/3.js
new file mode 100644
index 0000000..c69e629
--- /dev/null
+++ b/test/modules/root/order/3.js
@@ -0,0 +1,5 @@
+require('./6', function () {});
+require('./7', function () {});
+
+exports.value = 3;
+satisfyModule(3);
diff --git a/test/modules/root/order/4.js b/test/modules/root/order/4.js
new file mode 100644
index 0000000..bfdb6ce
--- /dev/null
+++ b/test/modules/root/order/4.js
@@ -0,0 +1,5 @@
+require('./7', function () {});
+require('./8', function () {});
+
+exports.value = 4;
+satisfyModule(4);
diff --git a/test/modules/root/order/5.js b/test/modules/root/order/5.js
new file mode 100644
index 0000000..0478e43
--- /dev/null
+++ b/test/modules/root/order/5.js
@@ -0,0 +1,4 @@
+require('./6', function () {});
+
+exports.value = 5;
+satisfyModule(5);
diff --git a/test/modules/root/order/6.js b/test/modules/root/order/6.js
new file mode 100644
index 0000000..a7f784a
--- /dev/null
+++ b/test/modules/root/order/6.js
@@ -0,0 +1,2 @@
+exports.value = 6;
+satisfyModule(6);
diff --git a/test/modules/root/order/7.js b/test/modules/root/order/7.js
new file mode 100644
index 0000000..2ffaf0f
--- /dev/null
+++ b/test/modules/root/order/7.js
@@ -0,0 +1,4 @@
+require('./2', function () {});
+
+exports.value = 7;
+satisfyModule(7);
diff --git a/test/modules/root/order/8.js b/test/modules/root/order/8.js
new file mode 100644
index 0000000..84c4999
--- /dev/null
+++ b/test/modules/root/order/8.js
@@ -0,0 +1,2 @@
+exports.value = 8;
+satisfyModule(8);
diff --git a/test/modules/root/order/index.js b/test/modules/root/order/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/test/modules/root/spa ce s.js b/test/modules/root/spa ce s.js
new file mode 100644
index 0000000..ebed3be
--- /dev/null
+++ b/test/modules/root/spa ce s.js
@@ -0,0 +1 @@
+exports.value = module.id;
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..a806727
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,206 @@
+/*!
+
+ require-kernel
+
+ Created by Chad Weider on 01/04/11.
+ Released to the Public Domain on 17/01/12.
+
+*/
+
+var assert = require('assert');
+var fs = require('fs');
+var util = require('util');
+var pathutil = require('path');
+var requireForPaths = require('../mock_require').requireForPaths;
+
+var modulesPath = pathutil.join(__dirname, 'modules');
+
+describe("require.define", function () {
+ it("should work", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ r.define("user/module.js", function (require, exports, module) {
+ exports.value = module.id;
+ });
+ r.define("user/module.js", function (require, exports, module) {
+ exports.value = "REDEFINED";
+ });
+ r.define({
+ "user/module1.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "user/module2.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "user/module3.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ });
+
+ assert.equal('user/module.js', r('user/module').value);
+ assert.equal('user/module1.js', r('user/module1').value);
+ assert.equal('user/module2.js', r('user/module2').value);
+ assert.equal('user/module3.js', r('user/module3').value);
+ });
+
+ it("should validate parameters", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ assert.throws(function () {r.define()}, "ArgumentError");
+ assert.throws(function () {r.define(null, null)}, "ArgumentError");
+ });
+});
+
+describe('require', function () {
+ var r = requireForPaths(modulesPath + '/root', modulesPath + '/library');
+ it("should resolve libraries", function () {
+ assert.equal('1.js', r('1.js').value);
+ assert.equal('/1.js', r('/1.js').value);
+ });
+
+ it("should resolve suffixes", function () {
+ assert.equal('/1.js', r('/1').value);
+ assert.equal(r('/1.js'), r('/1'));
+ });
+
+ it("should handle spaces", function () {
+ var r = requireForPaths(modulesPath + '/root', modulesPath + '/library');
+ assert.equal('/spa ce s.js', r('/spa ce s.js').value);
+ });
+
+ it("should handle questionable \"extra\" relative paths", function () {
+ var r = requireForPaths(modulesPath + '/root', modulesPath + '/library');
+ assert.equal('/../root/1.js', r('/../root/1').value);
+ assert.equal('/../library/1.js', r('../library/1').value);
+ });
+
+ it("should handle relative peths in library modules", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ r.define("main.js", function (require, exports, module) {
+ exports.sibling = require('./sibling');
+ });
+ r.define("sibling.js", function (require, exports, module) {
+ });
+ assert.equal(r('main.js').sibling, r('sibling.js'));
+ });
+
+ it("should resolve indexes correctly", function () {
+ var r = requireForPaths(modulesPath + '/index');
+ assert.equal('/index.js', r('/').value);
+ assert.equal('/index.js', r('/index').value);
+ assert.equal('/index/index.js', r('/index/').value);
+ assert.equal('/index/index.js', r('/index/index').value);
+ assert.equal('/index/index.js', r('/index/index.js').value);
+ assert.equal('/index/index/index.js', r('/index/index/').value);
+ assert.equal('/index/index/index.js', r('/index/index/index.js').value);
+ });
+
+ it("should normalize paths", function () {
+ var r = requireForPaths(modulesPath + '/index');
+ assert.equal('/index.js', r('./index').value);
+ assert.equal('/index.js', r('/./index').value);
+ assert.equal('/index/index.js', r('/index/index/../').value);
+ assert.equal('/index/index.js', r('/index/index/../../index/').value);
+ });
+
+ it("should validate parameters", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ assert.throws(function () {r(null)}, 'toString');
+ assert.throws(function () {r('1', '1')}, 'ArgumentError');
+ assert.throws(function () {r('1', '1', '1')}, 'ArgumentError');
+ });
+
+ it("should lookup nested libraries", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ r.setLibraryLookupComponent('node_modules');
+ r.define({
+ "thing0/index.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "thing1/index.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "/node_modules/thing1/index.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "/node_modules/thing/node_modules/thing2/index.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+ , "/node_modules/thing/dir/node_modules/thing3/index.js": function (require, exports, module) {
+ exports.value = module.id;
+ }
+
+ , "/node_modules/thing/dir/load_things.js": function (require, exports, module) {
+ assert.equal(require('thing3').value, '/node_modules/thing/dir/node_modules/thing3/index.js');
+ assert.equal(require('thing2').value, '/node_modules/thing/node_modules/thing2/index.js');
+ assert.equal(require('thing1').value, '/node_modules/thing1/index.js');
+ assert.equal(require('thing0').value, 'thing0/index.js');
+ }
+ });
+
+ r('/node_modules/thing/dir/load_things.js');
+ });
+
+ it("should detect cycles", function () {
+ var r = requireForPaths('/dev/null', '/dev/null');
+ r.define({
+ "one_cycle.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.one = require('one_cycle');
+ }
+
+ , "two_cycle.js": function (require, exports, module) {
+ exports.two = require('two_cycle.1');
+ }
+ , "two_cycle.1.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.two = require('two_cycle.2');
+ }
+ , "two_cycle.2.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.one = require('two_cycle.1');
+ }
+
+ , "n_cycle.js": function (require, exports, module) {
+ exports.two = require('n_cycle.1');
+ }
+ , "n_cycle.1.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.two = require('n_cycle.2');
+ }
+ , "n_cycle.2.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.three = require('n_cycle.3');
+ }
+ , "n_cycle.3.js": function (require, exports, module) {
+ exports.value = module.id;
+ exports.one = require('n_cycle.1');
+ }
+ });
+
+ assert.throws(function () {r('one_cycle')}, 'CircularDependency');
+ assert.throws(function () {r('two_cycle')}, 'CircularDependency');
+ assert.throws(function () {r('n_cycle')}, 'CircularDependency');
+ });
+
+ it("should avoid avoidable cycles", function () {
+ var r = requireForPaths();
+ r.define({
+ "non_cycle.js": function (require, exports, module) {
+ exports.value = module.id;
+ require("non_cycle.1.js");
+ }
+ , "non_cycle.1.js": function (require, exports, module) {
+ exports.value = module.id;
+ require("non_cycle.2.js", function (two) {exports.one = two});
+ }
+ , "non_cycle.2.js": function (require, exports, module) {
+ exports.value = module.id;
+ require("non_cycle.1.js", function (one) {exports.one = one});
+ }
+ });
+
+ assert.doesNotThrow(function () {
+ r("non_cycle.1.js");
+ }, 'CircularDependency');
+ });
+
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/require-kernel.js.git
More information about the Pkg-javascript-commits
mailing list