Skip to content

Commit

Permalink
first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
JeanSebTr committed Apr 3, 2012
1 parent 4e47909 commit 68705df
Show file tree
Hide file tree
Showing 4 changed files with 365 additions and 0 deletions.
41 changes: 41 additions & 0 deletions client/core.js
@@ -0,0 +1,41 @@
// ubiquity-require/client/core.js
var util = require('util');

var window = {};
(function(win) {
win = win || {};
//var pathReg = /^[a-z0-9\/. _-]+$/i;
var nativeModules = {};

function Module() {
this.defined = false; // the module is defined
this.isReady = false;
this.isCalled = false;
this.parents = [];
this.deps = [];
}

win.__filename = '';
win.__dirname = '';
var define = win.define = function(deps, cb) {
if(typeof deps == 'function') {
cb = deps;
deps = [];
}
if(typeof cb != 'function') {
throw new TypeError('You should pass a callback to define');
}
if(typeof deps == 'string') {
deps = [deps];
}
if(!(deps instanceof Array)) {
throw new TypeError('Dependencies must be specified in an Array');
}
};

define.addNative = function(name, cb) {
nativeModules[name] = cb();
};

})(window);

244 changes: 244 additions & 0 deletions client/path.js
@@ -0,0 +1,244 @@
// ubiquity-require/client/path.js

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var __pathDefineModule = function(){

var exports = {};

var paths = {};

// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}

// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}

return parts;
}

// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
var splitPath = function(filename) {
var result = splitPathRe.exec(filename);
return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
};

// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;

for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();

// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}

resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}

// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)

// Normalize the path
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
return !!p;
}), !resolvedAbsolute).join('/');

return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};

// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';

// Normalize the path
path = normalizeArray(path.split('/').filter(function(p) {
return !!p;
}), !isAbsolute).join('/');

if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}

return (isAbsolute ? '/' : '') + path;
};


// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(paths.filter(function(p, index) {
return p && typeof p === 'string';
}).join('/'));
};


// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);

function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}

var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}

if (start > end) return [];
return arr.slice(start, end - start + 1);
}

var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));

var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}

var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}

outputParts = outputParts.concat(toParts.slice(samePartsLength));

return outputParts.join('/');
};

exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];

if (!root && !dir) {
// No dirname whatsoever
return '.';
}

if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substring(0, dir.length - 1);
}

return root + dir;
};


exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};


exports.extname = function(path) {
return splitPath(path)[3];
};


exports.exists = function(path, callback) {
callback(!!paths[path]);
};


exports.existsSync = function(path) {
return !!paths[path];
};

exports.add = function(path, type) {
paths[path] = type;
};

exports.del = function(path) {
for(var p in paths) {
if(p == path || p.indexOf(path+'/') === 0) {
delete paths[p];
}
}
};

exports.get = function(path) {
return paths[path];
};

exports._makeLong = function(path) {
return path;
};

return exports;
};

// exports
if(define && define.model == 'ubiquity-require') {
define.addNative('path', __pathDefineModule);
}
else {
module.exports = __pathDefineModule();
}
16 changes: 16 additions & 0 deletions index.js
@@ -0,0 +1,16 @@

// loader
require('./server/require.js');

var urequire = {
// connect middleware
serve: function(req, res, next) {

}
};





module.exports = urequire;
64 changes: 64 additions & 0 deletions server/require.js
@@ -0,0 +1,64 @@
var path = require('path'),
vm = require('vm'),
fs = require('fs');

// don't be afraid of this undocumented module module
var Module = require('module');

var arequire = function(deps, cb) {
// fallback
if(typeof arguments[0] == 'string' && arguments.length == 0) {
return Module._load(arguments[0], this);
}
if(!cb && typeof deps == 'function') {
cb = deps;
deps = [];
}
if(typeof deps == 'string')
deps = [deps];
if(!cb)
throw Error('You MUST pass a callback to define.');
var mods = [];
for(var i=0,l=deps.length;i<l;i++) {
mods.push(Module._load(deps[i], this));
}
return cb.apply(module, mods);
};


require.extensions['.js'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
// strip utf8 BOM, SEE https://github.com/joyent/node/blob/master/lib/module.js#L450
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1);
}
content = content.replace(/^\#\!.*/, '');

function _require() {
return arequire.apply(module, arguments);
}
_require.resolve = function(request) {
return Module._resolveFilename(request, module);
};
_require.main = process.mainModule;
_require.extensions = Module._extensions;
_require.cache = Module._cache;

var p = path.dirname(require.main.filename),
file = (filename.indexOf(p) == 1)?filename.substr(p.length):filename,
ctx = {};
for (var k in global) {
ctx[k] = global[k];
}
ctx.define = function(deps, cb) {
module.exports = _require(deps, cb);
};
ctx.asyncRequire = true;
ctx.require = _require;
ctx.__filename = file;
ctx.__dirname = path.dirname(file);
ctx.module = module;
ctx.exports = module.exports;

vm.runInNewContext(content, ctx, file);
};

0 comments on commit 68705df

Please sign in to comment.