Skip to content

Commit

Permalink
Merge pull request #16 from AndreasMadsen/major
Browse files Browse the repository at this point in the history
Major update for 2.0. Thanks @AndreasMadsen
  • Loading branch information
alexgorbatchev committed Aug 24, 2013
2 parents e5f8112 + bb0969b commit e3d1e73
Show file tree
Hide file tree
Showing 82 changed files with 10,231 additions and 1,116 deletions.
116 changes: 112 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,117 @@
# Browser altenatives to built-in node.js modules

This is used by `browserify` module. Initially these files were in `node-browser-resolve`
but [disappeared in v1.0.1](https://github.com/shtylman/node-browser-resolve/commit/2799bcc316052a53fdafecd39576e14673a47ab0) which broke `browserify` dependency. This module is that missing
dependency.
but [disappeared in v1.0.1](https://github.com/shtylman/node-browser-resolve/commit/2799bcc316052a53fdafecd39576e14673a47ab0)
which broke `browserify` dependency. This module is that missing dependency.

**Would love to get test contributions**
## Browser support

"Forked" from `node-browser-resolve`, originally written by Roman Shtylman (@shtylman).
* Safari: latest
* Chrome: latest
* Firefox: latest
* Opera: latest
* Internet Explore: 8, 9, 10

## Documentation

Requireing this module gives you a simple map between the modulename and a
filepath to the module containing the shim. You can then point to these files
in your pseudo-node implementation. Note that beyond the nodecore modules
there is also a process module, there mimics `global.process` in node.

```javascript
require('browser-builtins');
```

```javascript
{
assert: '/user/node_modules/browser-builtins/builtin/assert.js',
child_process: '/user/node_modules/browser-builtins/builtin/child_process.js',
cluster: '/user/node_modules/browser-builtins/builtin/cluster.js',
dgram: '/user/node_modules/browser-builtins/builtin/dgram.js',
dns: '/user/node_modules/browser-builtins/builtin/dns.js',
domain: '/user/node_modules/browser-builtins/builtin/domain.js',
events: '/user/node_modules/browser-builtins/builtin/events.js',
fs: '/user/node_modules/browser-builtins/builtin/fs.js',
https: '/user/node_modules/browser-builtins/builtin/https.js',
net: '/user/node_modules/browser-builtins/builtin/net.js',
path: '/user/node_modules/browser-builtins/builtin/path.js',
process: '/user/node_modules/browser-builtins/builtin/process.js',
querystring: '/user/node_modules/browser-builtins/builtin/querystring.js',
readline: '/user/node_modules/browser-builtins/builtin/readline.js',
repl: '/user/node_modules/browser-builtins/builtin/repl.js',
stream: '/user/node_modules/browser-builtins/builtin/stream.js',
string_decoder: '/user/node_modules/browser-builtins/builtin/string_decoder.js',
sys: '/user/node_modules/browser-builtins/builtin/sys.js',
timers: '/user/node_modules/browser-builtins/builtin/timers.js',
tls: '/user/node_modules/browser-builtins/builtin/tls.js',
tty: '/user/node_modules/browser-builtins/builtin/tty.js',
url: '/user/node_modules/browser-builtins/builtin/url.js',
util: '/user/node_modules/browser-builtins/builtin/util.js',
punycode: '/user/node_modules/browser-builtins/node_modules/punycode/punycode.js',
http: '/user/node_modules/browser-builtins/node_modules/http-browserify/index.js',
vm: '/user/node_modules/browser-builtins/node_modules/vm-browserify/index.js',
crypto: '/user/node_modules/browser-builtins/node_modules/crypto-browserify/index.js',
console: '/user/node_modules/browser-builtins/node_modules/console-browserify/index.js',
zlib: '/user/node_modules/browser-builtins/node_modules/zlib-browserify/index.js',
buffer: '/user/node_modules/browser-builtins/node_modules/buffer-browserify/index.js',
constants: '/user/node_modules/browser-builtins/node_modules/constants-browserify/constants.json',
os: '/user/node_modules/browser-builtins/node_modules/os-browserify/browser.js'
}
```

## Contribute

When you find a bug in this module and want to fix it its a good idea to follow these steps:

> On a general note, please try to fix all issues either by coping from nodecore
> or by fixing it with a shim in the `_shims` file.
>
> Also since this module isn't just for browserify, you should always require
> the `Buffer` module and avoid using the `process` object.
1. Add a test (preferably in a new file) with the name `{modulename}-{issue}.js` in the `test/browser/` directory.
2. Check if the bug exists in node.js, if true `goto` _bug in nodecore_
3. Check if the module is outdated, if true `goto` _outdated module_
4. Check if the issue can be shimed, if true `goto` _fix with shims_
5. Sorry, as of this date all issues could be fixed with shims, you are on your own

#### bug in nodecore

1. Fix it in [nodecore](https://github.com/joyent/node)
2. When merged in nodecore `goto` _outdated module_

#### outdated module

1. Before you copy the module search for `shims` in the outdated module file.
2. Copypast the **entire** module from [nodecore](https://github.com/joyent/node) (checkout a stable branch).
3. Reimplement the `shims` from the outdated module file, `git diff` can help.
4. `goto` _test in browsers_

#### fix with shims

In the `builtin` directory there is a `_shims.js` file this contain all the
currently necessary shims. Most of these are incomple and writen specific
for this module collection. If you find that the current implementation is
insufficient try to improve it. If it lacks a feature just added that shim,
but try to keep the implementation at a minimum. Usually `TypeError` and
similar can be omitted.

#### test in browsers

This module is currently not integrated with testling-ci, but you can run testling
locally in order to run the tests.

1. First install: `npm install -g testling` and `npm install -g browserify`
2. `cd` intro this module directory
3. Run `browserify --transform ./test/browserify-transform.js test/browser/* | testling -u`
4. This gives you a url, go to that url in a modern browser (just not IE, even IE 10).
5. This will run the tests, if there was an issue you should fix it now
6. Run the tests again in IE 10, then IE 9 and at last IE 8 and fix any issues (see: _fix with shims_)
7. Test in the remaining supported browser, there shouldn't be any issues
8. You are done, make the Pull Request :+1:

## History

1. "Forked" from `node-browser-resolve`, originally written by Roman Shtylman (@shtylman).
2. Major update to node v0.10 and tests (@AndreasMadsen)
216 changes: 216 additions & 0 deletions builtin/_shims.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@


//
// The shims in this file are not fully implemented shims for the ES5
// features, but do work for the particular usecases there is in
// the other modules.
//

var toString = Object.prototype.toString;
var hasOwnProperty = Object.prototype.hasOwnProperty;

// Array.isArray is supported in IE9
function isArray(xs) {
return toString.call(xs) === '[object Array]';
}
exports.isArray = typeof Array.isArray === 'function' ? Array.isArray : isArray;

// Array.prototype.indexOf is supported in IE9
exports.indexOf = function indexOf(xs, x) {
if (xs.indexOf) return xs.indexOf(x);
for (var i = 0; i < xs.length; i++) {
if (x === xs[i]) return i;
}
return -1;
};

// Array.prototype.filter is supported in IE9
exports.filter = function filter(xs, fn) {
if (xs.filter) return xs.filter(fn);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (fn(xs[i], i, xs)) res.push(xs[i]);
}
return res;
};

// Array.prototype.forEach is supported in IE9
exports.forEach = function forEach(xs, fn, self) {
if (xs.forEach) return xs.forEach(fn, self);
for (var i = 0; i < xs.length; i++) {
fn.call(self, xs[i], i, xs);
}
};

// Array.prototype.map is supported in IE9
exports.map = function map(xs, fn) {
if (xs.map) return xs.map(fn);
var out = new Array(xs.length);
for (var i = 0; i < xs.length; i++) {
out[i] = fn(xs[i], i, xs);
}
return out;
};

// Array.prototype.reduce is supported in IE9
exports.reduce = function reduce(array, callback, opt_initialValue) {
if (array.reduce) return array.reduce(callback, opt_initialValue);
var value, isValueSet = false;

if (2 < arguments.length) {
value = opt_initialValue;
isValueSet = true;
}
for (var i = 0, l = array.length; l > i; ++i) {
if (array.hasOwnProperty(i)) {
if (isValueSet) {
value = callback(value, array[i], i, array);
}
else {
value = array[i];
isValueSet = true;
}
}
}

return value;
};

// String.prototype.substr - negative index don't work in IE8
if ('ab'.substr(-1) !== 'b') {
exports.substr = function (str, start, length) {
// did we get a negative start, calculate how much it is from the beginning of the string
if (start < 0) start = str.length + start;

// call the original function
return str.substr(start, length);
};
} else {
exports.substr = function (str, start, length) {
return str.substr(start, length);
};
}

// String.prototype.trim is supported in IE9
exports.trim = function (str) {
if (str.trim) return str.trim();
return str.replace(/^\s+|\s+$/g, '');
};

// Function.prototype.bind is supported in IE9
exports.bind = function () {
var args = Array.prototype.slice.call(arguments);
var fn = args.shift();
if (fn.bind) return fn.bind.apply(fn, args);
var self = args.shift();
return function () {
fn.apply(self, args.concat([Array.prototype.slice.call(arguments)]));
};
};

// Object.create is supported in IE9
function create(prototype, properties) {
var object;
if (prototype === null) {
object = { '__proto__' : null };
}
else {
if (typeof prototype !== 'object') {
throw new TypeError(
'typeof prototype[' + (typeof prototype) + '] != \'object\''
);
}
var Type = function () {};
Type.prototype = prototype;
object = new Type();
object.__proto__ = prototype;
}
if (typeof properties !== 'undefined' && Object.defineProperties) {
Object.defineProperties(object, properties);
}
return object;
}
exports.create = typeof Object.create === 'function' ? Object.create : create;

// Object.keys and Object.getOwnPropertyNames is supported in IE9 however
// they do show a description and number property on Error objects
function notObject(object) {
return ((typeof object != "object" && typeof object != "function") || object === null);
}

function keysShim(object) {
if (notObject(object)) {
throw new TypeError("Object.keys called on a non-object");
}

var result = [];
for (var name in object) {
if (hasOwnProperty.call(object, name)) {
result.push(name);
}
}
return result;
}

// getOwnPropertyNames is almost the same as Object.keys one key feature
// is that it returns hidden properties, since that can't be implemented,
// this feature gets reduced so it just shows the length property on arrays
function propertyShim(object) {
if (notObject(object)) {
throw new TypeError("Object.getOwnPropertyNames called on a non-object");
}

var result = keysShim(object);
if (exports.isArray(object) && exports.indexOf(object, 'length') === -1) {
result.push('length');
}
return result;
}

var keys = typeof Object.keys === 'function' ? Object.keys : keysShim;
var getOwnPropertyNames = typeof Object.getOwnPropertyNames === 'function' ?
Object.getOwnPropertyNames : propertyShim;

if (new Error().hasOwnProperty('description')) {
var ERROR_PROPERTY_FILTER = function (obj, array) {
if (toString.call(obj) === '[object Error]') {
array = exports.filter(array, function (name) {
return name !== 'description' && name !== 'number' && name !== 'message';
});
}
return array;
};

exports.keys = function (object) {
return ERROR_PROPERTY_FILTER(object, keys(object));
};
exports.getOwnPropertyNames = function (object) {
return ERROR_PROPERTY_FILTER(object, getOwnPropertyNames(object));
};
} else {
exports.keys = keys;
exports.getOwnPropertyNames = getOwnPropertyNames;
}

// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements
function valueObject(value, key) {
return { value: value[key] };
}

if (typeof Object.getOwnPropertyDescriptor === 'function') {
try {
Object.getOwnPropertyDescriptor({'a': 1}, 'a');
exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
} catch (e) {
// IE8 dom element issue - use a try catch and default to valueObject
exports.getOwnPropertyDescriptor = function (value, key) {
try {
return Object.getOwnPropertyDescriptor(value, key);
} catch (e) {
return valueObject(value, key);
}
};
}
} else {
exports.getOwnPropertyDescriptor = valueObject;
}

0 comments on commit e3d1e73

Please sign in to comment.