Browse Source

initial commit, not working.

jrburke 12 years ago
commit
62617521ea
7 changed files with 239 additions and 0 deletions
  1. 9 0
      README.md
  2. 200 0
      amdefine.js
  3. 0 0
      package.json
  4. 8 0
      tests/basic/a.js
  5. 5 0
      tests/basic/b.js
  6. 5 0
      tests/basic/sub/c.js
  7. 12 0
      tests/basic/sub/nested/d.js

+ 9 - 0
README.md

@@ -0,0 +1,9 @@
+
+
+## Test
+
+* require.toUrl
+* ask for require, exports, module but return a value.
+* ask for require, exports, module, modify exports but return value?
+* loader plugin
+* 

+ 200 - 0
amdefine.js

@@ -0,0 +1,200 @@
+
+/*jslint strict: false, nomen: false, plusplus: false */
+/*global require, module, process */
+
+var loaderCache = {},
+    makeRequire;
+
+/**
+ * Given a relative module name, like ./something, normalize it to
+ * a real name that can be mapped to a path.
+ * @param {String} name the relative name
+ * @param {String} baseName a real name that the name arg is relative
+ * to.
+ * @returns {String} normalized name
+ */
+function normalize(name, baseName) {
+    //Adjust any relative paths.
+    if (name && name.charAt(0) === ".") {
+        //If have a base name, try to normalize against it,
+        //otherwise, assume it is a top-level require that will
+        //be relative to baseUrl in the end.
+        if (baseName) {
+            //Convert baseName to array, and lop off the last part,
+            //so that . matches that "directory" and not name of the baseName's
+            //module. For instance, baseName of "one/two/three", maps to
+            //"one/two/three.js", but we want the directory, "one/two" for
+            //this normalization.
+            baseName = baseName.split("/");
+            baseName = baseName.slice(0, baseName.length - 1);
+
+            name = baseName.concat(name.split("/"));
+
+            //start trimDots
+            var i, part;
+            for (i = 0; (part = name[i]); i++) {
+                if (part === ".") {
+                    name.splice(i, 1);
+                    i -= 1;
+                } else if (part === "..") {
+                    if (i === 1 && (name[2] === '..' || name[0] === '..')) {
+                        //End of the line. Keep at least one non-dot
+                        //path segment at the front so it can be mapped
+                        //correctly to disk. Otherwise, there is likely
+                        //no path mapping for a path starting with '..'.
+                        //This can still fail, but catches the most reasonable
+                        //uses of ..
+                        break;
+                    } else if (i > 0) {
+                        name.splice(i - 1, 2);
+                        i -= 2;
+                    }
+                }
+            }
+            //end trimDots
+
+            name = name.join("/");
+        }
+    }
+    return name;
+}
+
+function makeNormalize(relName) {
+    return function (name) {
+        return normalize(name, relName);
+    };
+}
+
+function stringRequire(require, exports, module, id) {
+    //Split the ID by a ! so that
+    var index = id.indexOf('!'),
+        relId = module.id,
+        prefix, plugin;
+
+    if (index === -1) {
+        //Straight module lookup. If it is one of the special dependencies,
+        //deal with it, otherwise, delegate to node.
+        if (id === 'require') {
+            return makeRequire(require, exports, module);
+        } else if (id === 'exports') {
+            return exports;
+        } else if (id === 'module') {
+            return module;
+        } else {
+            return require(id);
+        }
+    } else {
+        //There is a plugin in play.
+        prefix = id.substring(0, index);
+        id = id.substring(index, id.length);
+
+        plugin = require(prefix);
+
+        if (plugin.normalize) {
+            id = plugin.normalize(id, makeNormalize(relId));
+        } else {
+            //Normalize the ID normally.
+            id = normalize(id, relId);
+        }
+
+        if (loaderCache[id]) {
+            return loaderCache[id];
+        } else {
+            plugin.load(id, makeRequire(require), function (value) {
+                loaderCache[id] = value;
+            }, {});
+
+            return loaderCache[id];
+        }
+    }
+}
+
+makeRequire = function (require, exports, module) {
+    return function (deps, callback) {
+        if (typeof deps === 'string') {
+            //Synchronous, single module require('')
+            return stringRequire(require, exports, module, deps);
+        } else {
+            //Array of dependencies with a callback.
+
+            //Convert the dependencies to modules.
+            deps = deps.map(function (depName) {
+                return stringRequire(require, exports, module, depName);
+            });
+
+            //Wait for next tick to call back the require call.
+            process.nextTick(function () {
+                callback.apply(null, deps);
+            });
+
+            //Keeps strict checking in komodo happy.
+            return undefined;
+        }
+    };
+};
+
+function amdefine(module) {
+
+console.log('amdefine called for module: ' + module.id);
+
+//debugger;
+    var require = module.require,
+        exports = module.exports,
+        alreadyCalled = false;
+
+    //Create a define function specific to the module asking for amdefine.
+    function define() {
+
+console.log('define called for module: ' + module.id);
+//debugger;
+
+        var args = arguments,
+            factory = args[args.length - 1],
+            isFactoryFunction = (typeof factory === 'function'),
+            deps, result;
+
+        //Only support one define call per file
+        //if (alreadyCalled) {
+        //    throw new Error('amdefine cannot be called more than once per file.');
+        //}
+        //alreadyCalled = true;
+
+        //Grab array of dependencies if it is there.
+        if (args.length > 1) {
+            deps = args[args.length - 2];
+            if (!Array.isArray(deps)) {
+                //deps is not an array, may be an ID. Discard it.
+                deps = null;
+            }
+        }
+
+        //If there are dependencies, they are strings, so need
+        //to convert them to dependency values.
+        if (deps) {
+            deps = deps.map(function (depName) {
+                return stringRequire(require, exports, module, depName);
+            });
+        } else if (isFactoryFunction) {
+            //Pass in the standard require, exports, module
+            deps = [makeRequire(require, exports, module), exports, module];
+        }
+
+        if (!isFactoryFunction) {
+            //Factory is an object that should just be used for the define call.
+            module.exports = factory;
+        } else {
+            //Call the factory with the right dependencies.
+            result = factory.apply(exports, deps);
+
+            if (result !== undefined) {
+                module.exports = result;
+            }
+        }
+    }
+
+    define.amd = {};
+
+    return define;
+}
+
+module.exports = amdefine;

+ 0 - 0
package.json


+ 8 - 0
tests/basic/a.js

@@ -0,0 +1,8 @@
+
+if (typeof define !== 'function') { var define = (require('../../amdefine'))(module); }
+
+define(['./b', './sub/nested/d'], function (b, d) {
+    console.log('b === ' + b.name);
+    console.log('d === ' + d.name);
+    console.log('c === ' + d.cName);
+});

+ 5 - 0
tests/basic/b.js

@@ -0,0 +1,5 @@
+if (typeof define !== 'function') { var define = (require('../../amdefine'))(module); }
+
+define({
+    name: 'b'
+});

+ 5 - 0
tests/basic/sub/c.js

@@ -0,0 +1,5 @@
+if (typeof define !== 'function') { var define = (require('../../../amdefine'))(module); }
+
+define({
+    name: 'c'
+});

+ 12 - 0
tests/basic/sub/nested/d.js

@@ -0,0 +1,12 @@
+if (typeof define !== 'function') { var define = (require('../../../../amdefine'))(module); }
+
+define('whatever', function (require, exports, module) {
+
+debugger;
+    var c = require('../c');
+
+    return {
+        name: 'd',
+        cName: c.name
+    };
+});