понедельник, 3 июня 2013 г.
EcmaScript 5 во всех браузерах
// Date.now();
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
// Number.isInteger(testValue);
if (!Number.isInteger) {
Number.isInteger = function isInteger (nVal) {
return typeof nVal === "number" && isFinite(nVal) && nVal > -9007199254740992 && nVal < 9007199254740992 && Math.floor(nVal) === nVal;
};
}
// String.trim();
if(!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g,'');
// или return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');
};
}
// String.supplant(data);
if(!String.prototype.supplant) {
String.prototype.supplant = function(o) {
return this.replace(/{([^{}]*)}/g,
function(a, b) {
var r = o[b];
return typeof r === 'string' ?
r : a;
}
);
}
}
/*
var template = '<table>'
+ <tr><td>{first}</td></tr>'
+ <tr><td>{last}</td></tr>'
+ '</table>';
var data = {
first: 'Carl',
last: 'Hollywood'
};
mydiv.innerHTML = template.supplant(data);
*/
// String.startsWith(searchString [, position]);
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
}
}
// String.endsWith(searchString [, position]);
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
position = position || this.length;
position = position - searchString.length;
return this.lastIndexOf(searchString) === position;
}
}
// String.contains(searchString [, position]);
if(!('contains' in String.prototype))
{
String.prototype.contains = function(str, startIndex)
{
return -1!== this.indexOf(str, startIndex);
};
}
// String.toArray();
if (!String.prototype.toArray) {
String.prototype.toArray = function(){
return this.split('');
};
}
// Array.every(callback[, thisObject]);
if (!Array.prototype.every)
{
Array.prototype.every = function(fun /*, thisp */)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t && !fun.call(thisp, t[i], i, t))
return false;
}
return true;
};
}
// Array.filter(callback[, thisObject]);
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisp*/)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var res = [];
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t)
{
var val = t[i]; // in case fun mutates this
if (fun.call(thisp, val, i, t))
res.push(val);
}
}
return res;
};
}
// Array.reduce(callback[, initialValue]);
if ('function' !== typeof Array.prototype.reduce) {
Array.prototype.reduce = function(callback, opt_initialValue){
'use strict';
if (null === this || 'undefined' === typeof this) {
// At the moment all modern browsers, that support strict mode, have
// native implementation of Array.prototype.reduce. For instance, IE8
// does not support strict mode, so this check is actually useless.
throw new TypeError(
'Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var index = 0, length = this.length >>> 0, value, isValueSet = false;
if (1 < arguments.length) {
value = opt_initialValue;
isValueSet = true;
}
for ( ; length > index; ++index) {
if (!this.hasOwnProperty(index)) continue;
if (isValueSet) {
value = callback(value, this[index], index, this);
} else {
value = this[index];
isValueSet = true;
}
}
if (!isValueSet) {
throw new TypeError('Reduce of empty array with no initial value');
}
return value;
};
}
// Array.reduceRight(callback[, initialValue]);
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback, opt_initialValue) {
'use strict';
if (null === this || 'undefined' === typeof this) {
// At the moment all modern browsers, that support strict mode, have
// native implementation of Array.prototype.reduceRight. For instance,
// IE8 does not support strict mode, so this check is actually useless.
throw new TypeError(
'Array.prototype.reduceRight called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var length = this.length >>> 0, index = length - 1,
value, isValueSet = false;
if (1 < arguments.length) {
value = opt_initialValue;
isValueSet = true;
}
for ( ; -1 < index; --index) {
if (!this.hasOwnProperty(index)) continue;
if (isValueSet) {
value = callback(value, this[index], index, this);
} else {
value = this[index];
isValueSet = true;
}
}
if (!isValueSet) {
throw new TypeError('Reduce of empty array with no initial value');
}
return value;
};
}
// Array.some(callback[, thisObject]);
if (!Array.prototype.some)
{
Array.prototype.some = function(fun /*, thisp */)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t && fun.call(thisp, t[i], i, t))
return true;
}
return false;
};
}
// Array.forEach(callback[, thisArg]);
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
}
}
// Array.isArray(obj);
if(!Array.isArray) {
Array.isArray = function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
}
/* или
if (typeof Array.isArray !== 'function') {
Array.isArray = function(value) {
return Array.prototype.toString.apply(value) === '[object Array]';
};
}
*/
// Array.map(callback[, thisArg]);
if (!Array.prototype.map) {
Array.prototype.map = function(callback, thisArg) {
var T, A, k;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + " is not a function");
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (thisArg) {
T = thisArg;
}
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
// the standard built-in constructor with that name and len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
// 8. Repeat, while k < len
while(k < len) {
var kValue, mappedValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[ k ];
// ii. Let mappedValue be the result of calling the Call internal method of callback
// with T as the this value and argument list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
// For best browser support, use the following:
A[ k ] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
// Array.indexOf(searchElement[, fromIndex]);
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
// Array.lastIndexOf(searchElement[, fromIndex]);
if (!Array.prototype.lastIndexOf)
{
Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (len === 0)
return -1;
var n = len;
if (arguments.length > 1)
{
n = Number(arguments[1]);
if (n != n)
n = 0;
else if (n != 0 && n != (1 / 0) && n != -(1 / 0))
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
var k = n >= 0
? Math.min(n, len - 1)
: len - Math.abs(n);
for (; k >= 0; k--)
{
if (k in t && t[k] === searchElement)
return k;
}
return -1;
};
}
// Array.delete(index);
if (!Array.prototype.delete)
{
Array.prototype.delete = function(index)
{
this.splice(index, 1);
return this;
}
}
// Math.imul(a, b);
if(!Math.prototype.imul) {
Math.prototype.imul = function(a, b) {
var ah = (a >>> 16) & 0xffff;
var al = a & 0xffff;
var bh = (b >>> 16) & 0xffff;
var bl = b & 0xffff;
// the shift by 0 fixes the sign on the high part
// the final |0 converts the unsigned value into a signed value
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
}
}
// JSON
// JSON.parse('JSONString');
// JSON.stringify(JSONObject);
if (!window.JSON) {
window.JSON = {
parse: function (sJSON) { return eval("(" + sJSON + ")"); },
stringify: function (vContent) {
if (vContent instanceof Object) {
var sOutput = "";
if (vContent.constructor === Array) {
for (var nId = 0; nId < vContent.length; sOutput += this.stringify(vContent[nId]) + ",", nId++);
return "[" + sOutput.substr(0, sOutput.length - 1) + "]";
}
if (vContent.toString !== Object.prototype.toString) { return "\"" + vContent.toString().replace(/"/g, "\\$&") + "\""; }
for (var sProp in vContent) { sOutput += "\"" + sProp.replace(/"/g, "\\$&") + "\":" + this.stringify(vContent[sProp]) + ","; }
return "{" + sOutput.substr(0, sOutput.length - 1) + "}";
}
return typeof vContent === "string" ? "\"" + vContent.replace(/"/g, "\\$&") + "\"" : String(vContent);
}
};
}
// Function.bind(thisArg[, arg1[, arg2[, ...]]]);
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
// Function.call(thisArg[, arg1[, arg2[, ...]]]);
Function.prototype.call = function(thisObject) {
return this.apply(thisObject, Array.prototype.slice.apply(arguments, [1]));
}
// Object.keys(obj);
if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
var result = [];
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) result.push(prop);
}
if (hasDontEnumBug) {
for (var i=0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
}
}
return result;
}
})()
};
// Object.create(proto [, propertiesObject ]);
if (!Object.create) {
Object.create = (function(){
function F(){}
return function(o){
if (arguments.length != 1) {
throw new Error('Object.create implementation only accepts one parameter.');
}
F.prototype = o
return new F()
}
})()
}
// Object.defineProperties(obj, props);
function defineProperties(obj, properties) {
function convertToDescriptor(desc) {
function hasProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function isCallable(v) {
// NB: modify as necessary if other values than functions are callable.
return typeof v === "function";
}
if (typeof desc !== "object" || desc === null)
throw new TypeError("bad desc");
var d = {};
if (hasProperty(desc, "enumerable"))
d.enumerable = !!obj.enumerable;
if (hasProperty(desc, "configurable"))
d.configurable = !!obj.configurable;
if (hasProperty(desc, "value"))
d.value = obj.value;
if (hasProperty(desc, "writable"))
d.writable = !!desc.writable;
if ( hasProperty(desc, "get") ) {
var g = desc.get;
if (!isCallable(g) && g !== "undefined")
throw new TypeError("bad get");
d.get = g;
}
if ( hasProperty(desc, "set") ) {
var s = desc.set;
if (!isCallable(s) && s !== "undefined")
throw new TypeError("bad set");
d.set = s;
}
if (("get" in d || "set" in d) && ("value" in d || "writable" in d))
throw new TypeError("identity-confused descriptor");
return d;
}
if (typeof obj !== "object" || obj === null)
throw new TypeError("bad obj");
properties = Object(properties);
var keys = Object.keys(properties);
var descs = [];
for (var i = 0; i < keys.length; i++)
descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
for (var i = 0; i < descs.length; i++)
Object.defineProperty(obj, descs[i][0], descs[i][1]);
return obj;
}
// Object.setPrototypeOf(object, prototype);
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
// Object.later(1000, 'method');
Object.prototype.later = function(msec, method){
var that = this;
var args = Array.prototype.slice.apply(arguments, [2]);
if (typeof method = 'string') {
method = that[method];
}
setTimeout(functino(){
method.apply(that, args);
}, msec);
return that;
}
// Element.addEventListener();
// Element.removeEventListener();
if (!Element.prototype.addEventListener) {
var oListeners = {};
function runListeners(oEvent) {
if (!oEvent) { oEvent = window.event; }
for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) {
for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
break;
}
}
}
Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
if (oListeners.hasOwnProperty(sEventType)) {
var oEvtListeners = oListeners[sEventType];
for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
}
if (nElIdx === -1) {
oEvtListeners.aEls.push(this);
oEvtListeners.aEvts.push([fListener]);
this["on" + sEventType] = runListeners;
} else {
var aElListeners = oEvtListeners.aEvts[nElIdx];
if (this["on" + sEventType] !== runListeners) {
aElListeners.splice(0);
this["on" + sEventType] = runListeners;
}
for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
if (aElListeners[iLstId] === fListener) { return; }
}
aElListeners.push(fListener);
}
} else {
oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
this["on" + sEventType] = runListeners;
}
};
Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
if (!oListeners.hasOwnProperty(sEventType)) { return; }
var oEvtListeners = oListeners[sEventType];
for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
}
if (nElIdx === -1) { return; }
for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
}
};
}
// Is in Strict Mode?
function in_strict_mode(){
return (function(){
return !this;
})();
}
function strict_mode_implemented(){
return (function(){
'use strict';
return !this;
})();
}
// window.document.getElementsByClassName('className');
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
window.document.getElementsByClassName(className) {
var results = [];
walkTheDOM(document.body, function(node) {
var a, c = node.className, i;
if (c) {
a = c.split(' ');
for (i = 0; i < a.length; i += 1) {
if (a[i] === className) {
results.push(node);
break;
}
}
}
}
return results;
}
// purgeEventHandlers(node) - удаление событий элемента перед его удалением
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function purgeEventHandlers(node){
walkTheDOM(node, function(e) {
for (var n in e) {
if (typeof e[n] === 'function') {
e[n] = null;
}
}
});
}
// sleep(milliseconds);
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий