oxjs/source/Ox/js/Fallback.js
2012-05-25 22:30:17 +02:00

304 lines
9.3 KiB
JavaScript

'use strict';
Ox.fallback = {};
(function(global) {
/*@
Ox.fallback.bind <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
<script>
Ox.test.object = {
get: function() {
return this.value;
},
value: 'foo'
};
Ox.test.get = Ox.test.object.get;
Ox.test.value = 'bar';
</script>
> Ox.test.object.get()
'foo'
> Ox.test.get()
'bar'
> Ox.fallback.bind.call(Ox.test.get, Ox.test.object)()
'foo'
@*/
Ox.fallback.bind = function(that) {
if (typeof this !== 'function') {
throw new TypeError();
}
var args = Array.prototype.slice.call(arguments, 1),
fn = function() {},
this_ = this,
ret = function() {
return this_.apply(
this instanceof fn ? this : that || global,
args.concat(Array.prototype.slice.call(arguments))
);
};
fn.prototype = this.prototype;
ret.prototype = new fn();
return ret;
};
})(this);
/*@
Ox.fallback.every <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
> Ox.fallback.every.call([0, 1, 2], function(v, i) { return v == i; })
true
> Ox.fallback.every.call([true, true, false], Ox.identity)
false
@*/
Ox.fallback.every = function(iterator, that) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0, ret = true;
for (i = 0; i < length; i++) {
if (i in array && !iterator.call(that, array[i], i, array)) {
ret = false;
break;
}
}
return ret;
};
/*@
Ox.fallback.filter <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
> Ox.fallback.filter.call([2, 1, 0], function(v, i) { return v == i; })
[1]
@*/
Ox.fallback.filter = function(iterator, that) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0, ret = [], value;
for (i = 0; i < length; i++) {
// save value in case iterator mutates it
if (i in array && iterator.call(that, value = array[i], i, array)) {
ret.push(value);
}
}
return ret;
};
/*@
Ox.fallback.forEach <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach
<script>
Ox.test.array = [];
Ox.fallback.forEach.call([1, 2, 3], function(v, i) { Ox.test.array.push([v, i])})
</script>
> Ox.test.array
[[1, 0], [2, 1], [3, 2]]
@*/
Ox.fallback.forEach = function(iterator, that) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0;
for (i = 0; i < length; i++) {
if (i in array) {
iterator.call(that, array[i], i, array);
}
}
};
/*@
Ox.fallback.indexOf <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
> Ox.fallback.indexOf.call([1, 2, 3, 2, 1], 2)
1
> Ox.fallback.indexOf.call([1, 2, 3, 2, 1], 4)
-1
@*/
Ox.fallback.indexOf = function(value) {
if (this === void 0 || this === null) {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0, ret = -1;
for (i = 0; i < length; i++) {
if (i in array && array[i] === value) {
ret = i;
break;
}
}
return ret;
};
/*@
Ox.fallback.isArray <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
> Ox.fallback.isArray([])
true
> Ox.fallback.isArray((function() { return arguments; }()))
false
> Ox.fallback.isArray({0: 0, length: 1})
false
@*/
Ox.fallback.isArray = function(value) {
return Object.prototype.toString.call(value) == '[object Array]';
};
/*@
Ox.fallback.keys <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
> Ox.fallback.keys({a: 1, b: 2, c: 3})
['a', 'b', 'c']
@*/
Ox.fallback.keys = function(object) {
if (object !== Object(object)) {
throw new TypeError();
}
var key, ret = [];
for (key in object) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
ret.push(key);
}
}
return ret;
};
/*@
Ox.fallback.lastIndexOf <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
> Ox.fallback.lastIndexOf.call([1, 2, 3, 2, 1], 2)
3
> Ox.fallback.lastIndexOf.call([1, 2, 3, 2, 1], 4)
-1
@*/
Ox.fallback.lastIndexOf = function(value) {
if (this === void 0 || this === null) {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0, ret = -1;
for (i = length - 1; i >= 0; i--) {
if (i in array && array[i] === value) {
ret = i;
break;
}
}
return ret;
};
/*@
Ox.fallback.map <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
> Ox.fallback.map.call([2, 1, 0], function(v, i) { return v == i; })
[false, true, false]
@*/
Ox.fallback.map = function(iterator, that) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0,
ret = new Array(length);
for (i = 0; i < length; i++) {
if (i in array) {
ret[i] = iterator.call(that, array[i], i, array);
}
}
return ret;
};
/*@
Ox.fallback.reduce <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
> Ox.fallback.reduce.call([1, 2, 3], function(p, c, i) { return p + c + i; }, 1)
10
@*/
Ox.fallback.reduce = function(iterator, ret) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length;
if (!length && ret === void 0) {
throw new TypeError();
}
if (ret === void 0) {
ret = array[0];
i = 1;
}
for (i = i || 0; i < length; i++) {
if (i in array) {
ret = iterator.call(void 0, ret, array[i], i, array);
}
}
return ret;
};
/*@
Ox.fallback.reduceRight <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduceRight
> Ox.fallback.reduceRight.call([1, 2, 3], function(p, c, i) { return p + c + i; }, 1)
10
@*/
Ox.fallback.reduceRight = function(iterator, ret) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length;
if (!length && ret === void 0) {
throw new TypeError();
}
if (ret === void 0) {
ret = array[length - 1];
i = length - 2;
}
for (i = i || length - 1; i >= 0; i--) {
if (i in array) {
ret = iterator.call(void 0, ret, array[i], i, array);
}
}
return ret;
};
/*@
Ox.fallback.some <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
> Ox.fallback.some.call([2, 1, 0], function(v, i) { return v == i; })
true
> Ox.fallback.some.call([false, false, false], Ox.identity)
false
@*/
Ox.fallback.some = function(iterator, that) {
if (this === void 0 || this === null || typeof iterator !== 'function') {
throw new TypeError();
}
var array = Object(this), i, length = array.length >>> 0, ret = false;
for (i = 0; i < length; i++) {
if (i in array && iterator.call(that, array[i], i, array)) {
ret = true;
break;
}
}
return ret;
};
/*@
Ox.fallback.trim <f> see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/Trim
> Ox.fallback.trim.call(' foo ')
'foo'
@*/
Ox.fallback.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
(function(global) {
var log, method, object;
for (method in Ox.fallback) {
object = method == 'bind' ? Function.prototype
: method == 'isArray' ? Array
: method == 'keys' ? Object
: method == 'trim' ? String.prototype
: Array.prototype;
if (!object[method]) {
object[method] = Ox.fallback[method];
}
}
// In IE8, window.console.log is an object,
// in IE9, window.console.log.apply is undefined
// see http://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function
if (global.console) {
if (typeof global.console.log !== 'function') {
log = global.console.log;
global.console.log = function() {
log(Array.prototype.slice.call(arguments).join(' '));
}
} else if (!global.console.log.apply) {
global.console.log = Function.prototype.bind.call(
global.console.log, global.console
);
}
}
})(this);