diff options
author | John Christopher Anderson <jchris@apache.org> | 2010-09-12 09:03:38 +0000 |
---|---|---|
committer | John Christopher Anderson <jchris@apache.org> | 2010-09-12 09:03:38 +0000 |
commit | da6167eb1d0c893925b98116fe2c17cd20e36760 (patch) | |
tree | 4a476e8cfe015378918998aadd8fc27ac1958d22 /share | |
parent | ce44c0efd3a79843e5504c32c1147bd2c64d0331 (diff) |
commonjs require no longer creates circular references
git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.0.x@996269 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'share')
-rw-r--r-- | share/server/util.js | 64 | ||||
-rw-r--r-- | share/www/script/test/design_docs.js | 6 |
2 files changed, 41 insertions, 29 deletions
diff --git a/share/server/util.js b/share/server/util.js index 9cc464c3..77b934ed 100644 --- a/share/server/util.js +++ b/share/server/util.js @@ -10,36 +10,50 @@ // License for the specific language governing permissions and limitations under // the License. -var resolveModule = function(names, parent, current, path) { +var resolveModule = function(names, mod, root) { if (names.length == 0) { - if (typeof current != "string") { + if (typeof mod.current != "string") { throw ["error","invalid_require_path", - 'Must require a JavaScript string, not: '+(typeof current)]; + 'Must require a JavaScript string, not: '+(typeof mod.current)]; + } + return { + current : mod.current, + parent : mod.parent, + id : mod.id, + exports : {} } - return [current, parent, path]; } // we need to traverse the path var n = names.shift(); if (n == '..') { - if (!(parent && parent.parent)) { - throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)]; + if (!(mod.parent && mod.parent.parent)) { + throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)]; } - path = path.slice(0, path.lastIndexOf('/')); - return resolveModule(names, parent.parent.parent, parent.parent, path); + return resolveModule(names, { + id : mod.id.slice(0, mod.id.lastIndexOf('/')), + parent : mod.parent.parent.parent, + current : mod.parent.parent.current + }); } else if (n == '.') { - if (!parent) { - throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)]; + if (!mod.parent) { + throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)]; } - return resolveModule(names, parent.parent, parent, path); + return resolveModule(names, { + parent : mod.parent.parent, + current : mod.parent.current, + id : mod.id + }); + } else if (root) { + mod = {current : root}; } - if (!current[n]) { - throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(current)]; + if (!mod.current[n]) { + throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(mod.current)]; } - var p = current; - current = current[n]; - current.parent = p; - path = path ? path + '/' + n : n; - return resolveModule(names, p, current, path); + return resolveModule(names, { + current : mod.current[n], + parent : mod, + id : mod.id ? mod.id + '/' + n : n + }); }; var Couch = { @@ -52,19 +66,17 @@ var Couch = { try { if (sandbox) { if (ddoc) { - var require = function(name, parent) { - if (!parent) {parent = {}}; - var resolved = resolveModule(name.split('/'), parent.actual, ddoc, parent.id); - var s = "function (module, exports, require) { " + resolved[0] + " }"; - var module = {id:resolved[2], actual:resolved[1]}; - module.exports = {}; + var require = function(name, module) { + module = module || {}; + var newModule = resolveModule(name.split('/'), module, ddoc); + var s = "function (module, exports, require) { " + newModule.current + " }"; try { var func = sandbox ? evalcx(s, sandbox) : eval(s); - func.apply(sandbox, [module, module.exports, function(name) {return require(name, module)}]); + func.apply(sandbox, [newModule, newModule.exports, function(name) {return require(name, newModule)}]); } catch(e) { throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()]; } - return module.exports; + return newModule.exports; } sandbox.require = require; } diff --git a/share/www/script/test/design_docs.js b/share/www/script/test/design_docs.js index e62951ac..2e3e1db1 100644 --- a/share/www/script/test/design_docs.js +++ b/share/www/script/test/design_docs.js @@ -41,8 +41,8 @@ function() { whatever : { stringzone : "exports.string = 'plankton';", commonjs : { - whynot : "exports.test = require('../stringzone')", - upper : "exports.testing = require('./whynot').test.string.toUpperCase()+module.id" + whynot : "exports.test = require('../stringzone'); exports.foo = require('whatever/stringzone');", + upper : "exports.testing = require('./whynot').test.string.toUpperCase()+module.id+require('./whynot').foo.string" } }, views: { @@ -86,7 +86,7 @@ function() { // test commonjs require var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/requirey"); T(xhr.status == 200); - TEquals("PLANKTONwhatever/commonjs/upper", xhr.responseText); + TEquals("PLANKTONwhatever/commonjs/upperplankton", xhr.responseText); // test that we get design doc info back var dinfo = db.designInfo("_design/test"); |