560 lines
18 KiB
JavaScript
560 lines
18 KiB
JavaScript
if (typeof Object.assign != 'function') {
|
||
// Must be writable: true, enumerable: false, configurable: true
|
||
Object.defineProperty(Object, "assign", {
|
||
value: function assign(target, varArgs) { // .length of function is 2
|
||
'use strict';
|
||
if (target == null) { // TypeError if undefined or null
|
||
throw new TypeError('Cannot convert undefined or null to object');
|
||
}
|
||
|
||
var to = Object(target);
|
||
|
||
for (var index = 1; index < arguments.length; index++) {
|
||
var nextSource = arguments[index];
|
||
|
||
if (nextSource != null) { // Skip over if undefined or null
|
||
for (var nextKey in nextSource) {
|
||
// Avoid bugs when hasOwnProperty is shadowed
|
||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||
to[nextKey] = nextSource[nextKey];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return to;
|
||
},
|
||
writable: true,
|
||
configurable: true
|
||
});
|
||
}
|
||
|
||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||
if (!Object.keys) {
|
||
Object.keys = (function() {
|
||
'use strict';
|
||
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 !== 'function' && (typeof obj !== 'object' || obj === null)) {
|
||
throw new TypeError('Object.keys called on non-object');
|
||
}
|
||
|
||
var result = [], prop, i;
|
||
|
||
for (prop in obj) {
|
||
if (hasOwnProperty.call(obj, prop)) {
|
||
result.push(prop);
|
||
}
|
||
}
|
||
|
||
if (hasDontEnumBug) {
|
||
for (i = 0; i < dontEnumsLength; i++) {
|
||
if (hasOwnProperty.call(obj, dontEnums[i])) {
|
||
result.push(dontEnums[i]);
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
}());
|
||
}
|
||
|
||
// const PromisePolyfill = require('es6-promise').Promise;
|
||
// if (!window.Promise) {
|
||
// window.Promise = PromisePolyfill
|
||
// }
|
||
|
||
// https://tc39.github.io/ecma262/#sec-array.prototype.find
|
||
if (!Array.prototype.find) {
|
||
Object.defineProperty(Array.prototype, 'find', {
|
||
value: function(predicate) {
|
||
// 1. Let O be ? ToObject(this value).
|
||
if (this == null) {
|
||
throw TypeError('"this" is null or not defined');
|
||
}
|
||
|
||
var o = Object(this);
|
||
|
||
// 2. Let len be ? ToLength(? Get(O, "length")).
|
||
var len = o.length >>> 0;
|
||
|
||
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
|
||
if (typeof predicate !== 'function') {
|
||
throw TypeError('predicate must be a function');
|
||
}
|
||
|
||
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||
var thisArg = arguments[1];
|
||
|
||
// 5. Let k be 0.
|
||
var k = 0;
|
||
|
||
// 6. Repeat, while k < len
|
||
while (k < len) {
|
||
// a. Let Pk be ! ToString(k).
|
||
// b. Let kValue be ? Get(O, Pk).
|
||
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
|
||
// d. If testResult is true, return kValue.
|
||
var kValue = o[k];
|
||
if (predicate.call(thisArg, kValue, k, o)) {
|
||
return kValue;
|
||
}
|
||
// e. Increase k by 1.
|
||
k++;
|
||
}
|
||
|
||
// 7. Return undefined.
|
||
return undefined;
|
||
},
|
||
configurable: true,
|
||
writable: true
|
||
});
|
||
}
|
||
|
||
if (!Array.prototype.findIndex) {
|
||
Array.prototype.findIndex = function(predicate) {
|
||
if (this == null) {
|
||
throw new TypeError('Array.prototype.findIndex called on null or undefined');
|
||
}
|
||
if (typeof predicate !== 'function') {
|
||
throw new TypeError('predicate must be a function');
|
||
}
|
||
var list = Object(this);
|
||
var length = list.length >>> 0;
|
||
var thisArg = arguments[1];
|
||
var value;
|
||
|
||
for (var i = 0; i < length; i++) {
|
||
value = list[i];
|
||
if (predicate.call(thisArg, value, i, list)) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
};
|
||
}
|
||
|
||
if (!Array.prototype.filter) {
|
||
Array.prototype.filter = function(fun/*, thisArg*/) {
|
||
'use strict';
|
||
|
||
if (this === void 0 || this === null) {
|
||
throw new TypeError();
|
||
}
|
||
|
||
var t = Object(this);
|
||
var len = t.length >>> 0;
|
||
if (typeof fun !== 'function') {
|
||
throw new TypeError();
|
||
}
|
||
|
||
var res = [];
|
||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||
for (var i = 0; i < len; i++) {
|
||
if (i in t) {
|
||
var val = t[i];
|
||
|
||
// NOTE: Technically this should Object.defineProperty at
|
||
// the next index, as push can be affected by
|
||
// properties on Object.prototype and Array.prototype.
|
||
// But that method's new, and collisions should be
|
||
// rare, so use the more-compatible alternative.
|
||
if (fun.call(thisArg, val, i, t)) {
|
||
res.push(val);
|
||
}
|
||
}
|
||
}
|
||
|
||
return res;
|
||
};
|
||
}
|
||
|
||
if (!String.prototype.trim) {
|
||
String.prototype.trim = function () {
|
||
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
||
};
|
||
}
|
||
|
||
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.prototype.pbind = function() {
|
||
var args = Array.prototype.slice.call(arguments);
|
||
args.unshift(window);
|
||
return this.bind.apply(this, args);
|
||
};
|
||
|
||
// Fix for Samsung Browser
|
||
if (!Function.prototype.ToString) {
|
||
Function.prototype.ToString = function () {
|
||
return this.toString();
|
||
}
|
||
}
|
||
|
||
if (!String.prototype.startsWith) {
|
||
String.prototype.startsWith = function(searchString, position){
|
||
position = position || 0;
|
||
return this.substr(position, searchString.length) === searchString;
|
||
};
|
||
}
|
||
|
||
if (!String.prototype.endsWith) {
|
||
String.prototype.endsWith = function(searchString, position) {
|
||
var subjectString = this.toString();
|
||
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
|
||
position = subjectString.length;
|
||
}
|
||
position -= searchString.length;
|
||
var lastIndex = subjectString.lastIndexOf(searchString, position);
|
||
return lastIndex !== -1 && lastIndex === position;
|
||
};
|
||
}
|
||
|
||
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
|
||
if (!Array.prototype.includes) {
|
||
Object.defineProperty(Array.prototype, 'includes', {
|
||
value: function(searchElement, fromIndex) {
|
||
|
||
// 1. Let O be ? ToObject(this value).
|
||
if (this == null) {
|
||
throw new TypeError('"this" is null or not defined');
|
||
}
|
||
|
||
var o = Object(this);
|
||
|
||
// 2. Let len be ? ToLength(? Get(O, "length")).
|
||
var len = o.length >>> 0;
|
||
|
||
// 3. If len is 0, return false.
|
||
if (len === 0) {
|
||
return false;
|
||
}
|
||
|
||
// 4. Let n be ? ToInteger(fromIndex).
|
||
// (If fromIndex is undefined, this step produces the value 0.)
|
||
var n = fromIndex | 0;
|
||
|
||
// 5. If n ≥ 0, then
|
||
// a. Let k be n.
|
||
// 6. Else n < 0,
|
||
// a. Let k be len + n.
|
||
// b. If k < 0, let k be 0.
|
||
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
|
||
|
||
// 7. Repeat, while k < len
|
||
while (k < len) {
|
||
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
|
||
// b. If SameValueZero(searchElement, elementK) is true, return true.
|
||
// c. Increase k by 1.
|
||
// NOTE: === provides the correct "SameValueZero" comparison needed here.
|
||
if (o[k] === searchElement) {
|
||
return true;
|
||
}
|
||
k++;
|
||
}
|
||
|
||
// 8. Return false
|
||
return false;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.21
|
||
// Ссылка (en): http://es5.github.io/#x15.4.4.21
|
||
// Ссылка (ru): http://es5.javascript.ru/x15.4.html#x15.4.4.21
|
||
if (!Array.prototype.reduce) {
|
||
Array.prototype.reduce = function(callback/*, initialValue*/) {
|
||
'use strict';
|
||
if (this == null) {
|
||
throw new TypeError('Array.prototype.reduce called on null or undefined');
|
||
}
|
||
if (typeof callback !== 'function') {
|
||
throw new TypeError(callback + ' is not a function');
|
||
}
|
||
var t = Object(this), len = t.length >>> 0, k = 0, value;
|
||
if (arguments.length >= 2) {
|
||
value = arguments[1];
|
||
} else {
|
||
while (k < len && ! (k in t)) {
|
||
k++;
|
||
}
|
||
if (k >= len) {
|
||
throw new TypeError('Reduce of empty array with no initial value');
|
||
}
|
||
value = t[k++];
|
||
}
|
||
for (; k < len; k++) {
|
||
if (k in t) {
|
||
value = callback(value, t[k], k, t);
|
||
}
|
||
}
|
||
return value;
|
||
};
|
||
}
|
||
|
||
|
||
Array.prototype.pushOnce = function(value) {
|
||
if (!this.includes(value)) {
|
||
this.push(value)
|
||
}
|
||
}
|
||
|
||
Array.prototype.removeOnce = function(value) {
|
||
let index = this.indexOf(value)
|
||
if (index !== -1) {
|
||
this.splice(index, 1)
|
||
}
|
||
}
|
||
|
||
// Production steps of ECMA-262, Edition 5, 15.4.4.18
|
||
// Reference: http://es5.github.io/#x15.4.4.18
|
||
if (!Array.prototype.forEach) {
|
||
|
||
Array.prototype.forEach = function(callback/*, thisArg*/) {
|
||
|
||
var T, 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 (arguments.length > 1) {
|
||
T = arguments[1];
|
||
}
|
||
|
||
// 6. Let k be 0.
|
||
k = 0;
|
||
|
||
// 7. Repeat while k < len.
|
||
while (k < len) {
|
||
|
||
var kValue;
|
||
|
||
// 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. Call the Call internal method of callback with T as
|
||
// the this value and argument list containing kValue, k, and O.
|
||
callback.call(T, kValue, k, O);
|
||
}
|
||
// d. Increase k by 1.
|
||
k++;
|
||
}
|
||
// 8. return undefined.
|
||
};
|
||
}
|
||
|
||
|
||
if (!Array.isArray) {
|
||
Array.isArray = function(arg) {
|
||
return Object.prototype.toString.call(arg) === '[object Array]';
|
||
};
|
||
}
|
||
|
||
|
||
// Production steps of ECMA-262, Edition 6, 22.1.2.1
|
||
if (!Array.from) {
|
||
Array.from = (function () {
|
||
var toStr = Object.prototype.toString;
|
||
var isCallable = function (fn) {
|
||
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
|
||
};
|
||
var toInteger = function (value) {
|
||
var number = Number(value);
|
||
if (isNaN(number)) { return 0; }
|
||
if (number === 0 || !isFinite(number)) { return number; }
|
||
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
||
};
|
||
var maxSafeInteger = Math.pow(2, 53) - 1;
|
||
var toLength = function (value) {
|
||
var len = toInteger(value);
|
||
return Math.min(Math.max(len, 0), maxSafeInteger);
|
||
};
|
||
|
||
// The length property of the from method is 1.
|
||
return function from(arrayLike/*, mapFn, thisArg */) {
|
||
// 1. Let C be the this value.
|
||
var C = this;
|
||
|
||
// 2. Let items be ToObject(arrayLike).
|
||
var items = Object(arrayLike);
|
||
|
||
// 3. ReturnIfAbrupt(items).
|
||
if (arrayLike == null) {
|
||
throw new TypeError('Array.from requires an array-like object - not null or undefined');
|
||
}
|
||
|
||
// 4. If mapfn is undefined, then let mapping be false.
|
||
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
|
||
var T;
|
||
if (typeof mapFn !== 'undefined') {
|
||
// 5. else
|
||
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
|
||
if (!isCallable(mapFn)) {
|
||
throw new TypeError('Array.from: when provided, the second argument must be a function');
|
||
}
|
||
|
||
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||
if (arguments.length > 2) {
|
||
T = arguments[2];
|
||
}
|
||
}
|
||
|
||
// 10. Let lenValue be Get(items, "length").
|
||
// 11. Let len be ToLength(lenValue).
|
||
var len = toLength(items.length);
|
||
|
||
// 13. If IsConstructor(C) is true, then
|
||
// 13. a. Let A be the result of calling the [[Construct]] internal method
|
||
// of C with an argument list containing the single item len.
|
||
// 14. a. Else, Let A be ArrayCreate(len).
|
||
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
||
|
||
// 16. Let k be 0.
|
||
var k = 0;
|
||
// 17. Repeat, while k < len… (also steps a - h)
|
||
var kValue;
|
||
while (k < len) {
|
||
kValue = items[k];
|
||
if (mapFn) {
|
||
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
|
||
} else {
|
||
A[k] = kValue;
|
||
}
|
||
k += 1;
|
||
}
|
||
// 18. Let putStatus be Put(A, "length", len, true).
|
||
A.length = len;
|
||
// 20. Return A.
|
||
return A;
|
||
};
|
||
}());
|
||
}
|
||
|
||
// Production steps of ECMA-262, Edition 5, 15.4.4.17
|
||
// Reference: https://es5.github.io/#x15.4.4.17
|
||
if (!Array.prototype.some) {
|
||
Array.prototype.some = function(fun, thisArg) {
|
||
'use strict';
|
||
|
||
if (this == null) {
|
||
throw new TypeError('Array.prototype.some called on null or undefined');
|
||
}
|
||
|
||
if (typeof fun !== 'function') {
|
||
throw new TypeError();
|
||
}
|
||
|
||
var t = Object(this);
|
||
var len = t.length >>> 0;
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
if (i in t && fun.call(thisArg, t[i], i, t)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* String.padEnd()
|
||
* version 1.0.1
|
||
* Feature Chrome Firefox Internet Explorer Opera Safari Edge
|
||
* Basic support 57 48 (No) 44 10 15
|
||
* -------------------------------------------------------------------------------
|
||
*/
|
||
if (!String.prototype.padEnd) {
|
||
String.prototype.padEnd = function padEnd(targetLength, padString) {
|
||
targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
|
||
padString = String(typeof padString !== 'undefined' ? padString : ' ');
|
||
if (this.length > targetLength) {
|
||
return String(this);
|
||
} else {
|
||
targetLength = targetLength - this.length;
|
||
if (targetLength > padString.length) {
|
||
padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
|
||
}
|
||
return String(this) + padString.slice(0, targetLength);
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* String.padStart()
|
||
* version 1.0.1
|
||
* Feature Chrome Firefox Internet Explorer Opera Safari Edge
|
||
* Basic support 57 51 (No) 44 10 15
|
||
* -------------------------------------------------------------------------------
|
||
*/
|
||
if (!String.prototype.padStart) {
|
||
String.prototype.padStart = function padStart(targetLength, padString) {
|
||
targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
|
||
padString = String(typeof padString !== 'undefined' ? padString : ' ');
|
||
if (this.length > targetLength) {
|
||
return String(this);
|
||
} else {
|
||
targetLength = targetLength - this.length;
|
||
if (targetLength > padString.length) {
|
||
padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
|
||
}
|
||
return padString.slice(0, targetLength) + String(this);
|
||
}
|
||
};
|
||
} |