diff --git a/README.md b/README.md index 27a8ed3..143c105 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,10 @@ Polyfill Service the easy way +## Resources + +https://github.com/behnammodi/polyfill + +https://polyfill.io/v3/ + +https://ungap.github.io/ diff --git a/mod.js b/mod.js index aab04e5..69f6c80 100644 --- a/mod.js +++ b/mod.js @@ -1,11 +1,11 @@ -!function(window, document){ +!function(window, document){ 'use strict'; var urls = { 'cdn.jsdelivr.net/npm/whatwg-fetch@3.6.2/fetch.js':{ 'fetch':[window], - 'Headers':[window], - 'Request':[window], - 'Response':[window], + //'Headers':[window], + //'Request':[window], + //'Response':[window], }, 'cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js':{ 'Promise':[window] @@ -13,44 +13,31 @@ var urls = { 'polyfill.io/v3/polyfill.min.js?features=IntersectionObserver':{ 'IntersectionObserver':[window] }, + 'polyfill.io/v3/polyfill.min.js?features=ResizeObserver':{ + 'ResizeObserver':[window] + }, 'polyfill.io/v3/polyfill.min.js?features=AbortController':{ - 'AbortController':[window] + 'AbortController':[window], + //'AbortSignal': [window] }, 'polyfill.io/v3/polyfill.min.js?features=URL':{ - 'URL':[window], + 'URL':[window], // ie11: this will not work as it has "URL" but not as a constructor, what should we do? 'URLSearchParams':[window] }, - 'polyfill.io/v3/polyfill.js?features=ResizeObserver':{ - 'ResizeObserver':[window] - }, 'unpkg.com/@ungap/weakset':{ 'WeakSet':[window] }, - 'unpkg.com/@ungap/custom-elements/es.js':{ - 'customElements':[window] + 'unpkg.com/@ungap/custom-elements@0.1.15/es.js':{ + 'customElements':[document] }, - 'unpkg.com/@ungap/item':{ - 'item':[Array.prototype] - } - /* - 'polyfill.io/v3/polyfill.min.js?features=es2021':{ - 'keys':[Object], - 'flags':[RegExp.prototype], - 'Symbol':[window], - //'replace':[Symbol], - 'Symbol':[window], - 'replaceAll':[String.prototype], - } - */ }; -/* -They have internal depencies :( -var ftPolyfills = { +var lazyfills = { Array:{ from:1, of:1, prototype:{ + at:1, copyWithin:1, entries:1, fill:1, @@ -63,17 +50,21 @@ var ftPolyfills = { values:1, } }, - Element:{ - prototype:{ - toggleAttribute:1, - } - }, String:{ fromCodePoint:1, - + prototype:{ + at:1, + codePointAt:1, + endsWith:1, + includes:1, + padEnd:1, + padStart:1, + repeat:1, + startsWith:1 + } } }; -function ftFill(obj, realObj, rootUrl){ +function createUrls(obj, realObj, rootUrl){ var prop; for (prop in obj) { if (obj[prop] === 1) { @@ -82,12 +73,11 @@ function ftFill(obj, realObj, rootUrl){ urls[url] = {}; urls[url][prop] = [realObj]; } else { - ftFill(obj[prop], realObj[prop], rootUrl + prop + '/'); + createUrls(obj[prop], realObj[prop], rootUrl + prop + '.js'); } } } -ftFill(ftPolyfills, window, 'cdn.jsdelivr.net/gh/Financial-Times/polyfill-library@3/polyfills/'); -*/ +createUrls(lazyfills, window, 'cdn.jsdelivr.net/gh/nuxodin/lazyfill@0.0.1/polyfills/'); var url, props, prop, obj, objects, i; @@ -97,7 +87,7 @@ for (url in urls) { objects = props[prop]; for (i=0; obj=objects[i++];) { if (prop in obj) { - //console.log('not needed '+prop+' in '+url+'
') + console.log('not needed '+prop+' in '+url+'
') continue; } //console.log('"'+prop+'" not supported, adding getter'); @@ -115,12 +105,11 @@ function addGetter(obj, prop, url) { configurable: true, get: function() { delete obj[prop]; - console.log(prop+' needed loading sync'); + console.log(prop+' needed > loading sync, you may want to add the polyfill '+url); loadScriptSync('https://'+url); - //return c1Use.call(this, prop); return this[prop]; }, - set: function(v) { // needed? + set: function(v) { delete obj[prop]; obj[prop] = v; } diff --git a/polyfills/Array/from.js b/polyfills/Array/from.js new file mode 100644 index 0000000..c49c005 --- /dev/null +++ b/polyfills/Array/from.js @@ -0,0 +1,88 @@ +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; + }; + })(); +} diff --git a/polyfills/Array/of.js b/polyfills/Array/of.js new file mode 100644 index 0000000..185a46d --- /dev/null +++ b/polyfills/Array/of.js @@ -0,0 +1,5 @@ +if (!Array.of) { + Array.of = function () { + return Array.prototype.slice.call(arguments); + }; +} \ No newline at end of file diff --git a/polyfills/Array/prototype/at.js b/polyfills/Array/prototype/at.js new file mode 100644 index 0000000..5cd2731 --- /dev/null +++ b/polyfills/Array/prototype/at.js @@ -0,0 +1,8 @@ +if (!Array.prototype.at) { + Array.prototype.at = function(n){ + n = Math.trunc(n) || 0; + if (n < 0) n += this.length; + if (n < 0 || n >= this.length) return undefined; + return this[n]; + } +} \ No newline at end of file diff --git a/polyfills/Array/prototype/copyWithin.js b/polyfills/Array/prototype/copyWithin.js new file mode 100644 index 0000000..2d179ce --- /dev/null +++ b/polyfills/Array/prototype/copyWithin.js @@ -0,0 +1,70 @@ +if (!Array.prototype.copyWithin) { + Object.defineProperty(Array.prototype, 'copyWithin', { + configurable: true, + writable: true, + value: function (target, start /*, end*/) { + // Steps 1-2. + if (this == null) { + throw new TypeError('this is null or not defined'); + } + + var O = Object(this); + + // Steps 3-5. + var len = O.length >>> 0; + + // Steps 6-8. + var relativeTarget = target >> 0; + + var to = + relativeTarget < 0 + ? Math.max(len + relativeTarget, 0) + : Math.min(relativeTarget, len); + + // Steps 9-11. + var relativeStart = start >> 0; + + var from = + relativeStart < 0 + ? Math.max(len + relativeStart, 0) + : Math.min(relativeStart, len); + + // Steps 12-14. + var end = arguments[2]; + var relativeEnd = end === undefined ? len : end >> 0; + + var final = + relativeEnd < 0 + ? Math.max(len + relativeEnd, 0) + : Math.min(relativeEnd, len); + + // Step 15. + var count = Math.min(final - from, len - to); + + // Steps 16-17. + var direction = 1; + + if (from < to && to < from + count) { + direction = -1; + from += count - 1; + to += count - 1; + } + + // Step 18. + while (count > 0) { + if (from in O) { + O[to] = O[from]; + } else { + delete O[to]; + } + + from += direction; + to += direction; + count--; + } + + // Step 19. + return O; + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/entries.js b/polyfills/Array/prototype/entries.js new file mode 100644 index 0000000..4b730d9 --- /dev/null +++ b/polyfills/Array/prototype/entries.js @@ -0,0 +1,21 @@ +if (!Array.prototype.entries) { + Array.prototype.entries = function () { + function Iterator() { } + + Iterator.prototype.next = function () { + if (index > selfThis.length - 1) { + done = true; + } + if (done) { + return { value: undefined, done: true }; + } + return { value: [index, selfThis[index++]], done: false }; + }; + + var selfThis = this; + var index = 0; + var done; + + return new Iterator(); + }; +} \ No newline at end of file diff --git a/polyfills/Array/prototype/fill.js b/polyfills/Array/prototype/fill.js new file mode 100644 index 0000000..5abb397 --- /dev/null +++ b/polyfills/Array/prototype/fill.js @@ -0,0 +1,46 @@ +if (!Array.prototype.fill) { + Object.defineProperty(Array.prototype, 'fill', { + configurable: true, + writable: true, + value: function (value) { + // Steps 1-2. + if (this == null) { + throw new TypeError('this is null or not defined'); + } + + var O = Object(this); + + // Steps 3-5. + var len = O.length >>> 0; + + // Steps 6-7. + var start = arguments[1]; + var relativeStart = start >> 0; + + // Step 8. + var k = + relativeStart < 0 + ? Math.max(len + relativeStart, 0) + : Math.min(relativeStart, len); + + // Steps 9-10. + var end = arguments[2]; + var relativeEnd = end === undefined ? len : end >> 0; + + // Step 11. + var final = + relativeEnd < 0 + ? Math.max(len + relativeEnd, 0) + : Math.min(relativeEnd, len); + + // Step 12. + while (k < final) { + O[k] = value; + k++; + } + + // Step 13. + return O; + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/find.js b/polyfills/Array/prototype/find.js new file mode 100644 index 0000000..ac71504 --- /dev/null +++ b/polyfills/Array/prototype/find.js @@ -0,0 +1,45 @@ +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + configurable: true, + writable: true, + value: function (predicate) { + // 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 IsCallable(predicate) is false, throw a TypeError exception. + if (typeof predicate !== 'function') { + throw new 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; + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/findIndex.js b/polyfills/Array/prototype/findIndex.js new file mode 100644 index 0000000..23d971b --- /dev/null +++ b/polyfills/Array/prototype/findIndex.js @@ -0,0 +1,45 @@ +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + configurable: true, + writable: true, + value: function (predicate) { + // 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 IsCallable(predicate) is false, throw a TypeError exception. + if (typeof predicate !== 'function') { + throw new 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 k. + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return k; + } + // e. Increase k by 1. + k++; + } + + // 7. Return -1. + return -1; + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/flat.js b/polyfills/Array/prototype/flat.js new file mode 100644 index 0000000..99caff9 --- /dev/null +++ b/polyfills/Array/prototype/flat.js @@ -0,0 +1,19 @@ +if (!Array.prototype.flat) { + Object.defineProperty(Array.prototype, 'flat', { + configurable: true, + writable: true, + value: function () { + var stack = [].concat(this); + var result = []; + while (stack.length) { + var next = stack.pop(); + if (Array.isArray(next)) { + stack.push.apply(stack, next); + } else { + result.push(next); + } + } + return result.reverse(); + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/flatMap.js b/polyfills/Array/prototype/flatMap.js new file mode 100644 index 0000000..22335d9 --- /dev/null +++ b/polyfills/Array/prototype/flatMap.js @@ -0,0 +1,9 @@ +if (!Array.prototype.flatMap) { + Object.defineProperty(Array.prototype, 'flatMap', { + configurable: true, + writable: true, + value: function () { + return Array.prototype.map.apply(this, arguments).flat(1); + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/includes.js b/polyfills/Array/prototype/includes.js new file mode 100644 index 0000000..7ef43dd --- /dev/null +++ b/polyfills/Array/prototype/includes.js @@ -0,0 +1,57 @@ +if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + configurable: true, + writable: true, + 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); + + function sameValueZero(x, y) { + return ( + x === y || + (typeof x === 'number' && + typeof y === 'number' && + isNaN(x) && + isNaN(y)) + ); + } + + // 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. + if (sameValueZero(o[k], searchElement)) { + return true; + } + k++; + } + + // 8. Return false + return false; + }, + }); +} \ No newline at end of file diff --git a/polyfills/Array/prototype/item.js b/polyfills/Array/prototype/item.js new file mode 100644 index 0000000..e69de29 diff --git a/polyfills/Array/prototype/keys.js b/polyfills/Array/prototype/keys.js new file mode 100644 index 0000000..9046fa6 --- /dev/null +++ b/polyfills/Array/prototype/keys.js @@ -0,0 +1,21 @@ +if (!Array.prototype.keys) { + Array.prototype.keys = function () { + function Iterator() { } + + Iterator.prototype.next = function () { + if (index > selfThis.length - 1) { + done = true; + } + if (done) { + return { value: undefined, done: true }; + } + return { value: index++, done: false }; + }; + + var selfThis = this; + var index = 0; + var done; + + return new Iterator(); + }; +} \ No newline at end of file diff --git a/polyfills/Array/prototype/values.js b/polyfills/Array/prototype/values.js new file mode 100644 index 0000000..af25f5b --- /dev/null +++ b/polyfills/Array/prototype/values.js @@ -0,0 +1,21 @@ +if (!Array.prototype.values) { + Array.prototype.values = function () { + function Iterator() { } + + Iterator.prototype.next = function () { + if (index > selfThis.length - 1) { + done = true; + } + if (done) { + return { value: undefined, done: true }; + } + return { value: selfThis[index++], done: false }; + }; + + var selfThis = this; + var index = 0; + var done; + + return new Iterator(); + }; +} \ No newline at end of file diff --git a/polyfills/String/fromCodePoint.js b/polyfills/String/fromCodePoint.js new file mode 100644 index 0000000..f80b163 --- /dev/null +++ b/polyfills/String/fromCodePoint.js @@ -0,0 +1,60 @@ +if (!String.fromCodePoint) { + (function () { + var defineProperty = (function () { + try { + var object = {}; + var $defineProperty = Object.defineProperty; + var result = $defineProperty(object, object, object) && $defineProperty; + } catch (error) { } + return result; + })(); + var stringFromCharCode = String.fromCharCode; + var floor = Math.floor; + var fromCodePoint = function () { + var MAX_SIZE = 0x4000; + var codeUnits = []; + var highSurrogate; + var lowSurrogate; + var index = -1; + var length = arguments.length; + if (!length) { + return ''; + } + var result = ''; + while (++index < length) { + var codePoint = Number(arguments[index]); + if ( + !isFinite(codePoint) || + codePoint < 0 || + codePoint > 0x10ffff || + floor(codePoint) != codePoint + ) { + throw RangeError('Invalid code point: ' + codePoint); + } + if (codePoint <= 0xffff) { + // BMP code point + codeUnits.push(codePoint); + } else { + codePoint -= 0x10000; + highSurrogate = (codePoint >> 10) + 0xd800; + lowSurrogate = (codePoint % 0x400) + 0xdc00; + codeUnits.push(highSurrogate, lowSurrogate); + } + if (index + 1 == length || codeUnits.length > MAX_SIZE) { + result += stringFromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } + } + return result; + }; + if (defineProperty) { + defineProperty(String, 'fromCodePoint', { + value: fromCodePoint, + configurable: true, + writable: true, + }); + } else { + String.fromCodePoint = fromCodePoint; + } + })(); +} \ No newline at end of file diff --git a/polyfills/String/prototype/at.js b/polyfills/String/prototype/at.js new file mode 100644 index 0000000..1b9a958 --- /dev/null +++ b/polyfills/String/prototype/at.js @@ -0,0 +1,18 @@ +if (!String.prototype.at) { + Object.defineProperty(String.prototype, "at", + { + value: function (n) { + // ToInteger() abstract op + n = Math.trunc(n) || 0; + // Allow negative indexing from the end + if (n < 0) n += this.length; + // OOB access is guaranteed to return undefined + if (n < 0 || n >= this.length) return undefined; + // Otherwise, this is just normal property access + return this[n]; + }, + writable: true, + enumerable: false, + configurable: true + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/codePointAt.js b/polyfills/String/prototype/codePointAt.js new file mode 100644 index 0000000..22475bf --- /dev/null +++ b/polyfills/String/prototype/codePointAt.js @@ -0,0 +1,36 @@ +if (!String.prototype.codePointAt) { + (function () { + var codePointAt = function (position) { + if (this == null) { + throw TypeError(); + } + var string = String(this); + var size = string.length; + var index = position ? Number(position) : 0; + if (index != index) { + index = 0; + } + if (index < 0 || index >= size) { + return undefined; + } + var first = string.charCodeAt(index); + var second; + if (first >= 0xd800 && first <= 0xdbff && size > index + 1) { + second = string.charCodeAt(index + 1); + if (second >= 0xdc00 && second <= 0xdfff) { + return (first - 0xd800) * 0x400 + second - 0xdc00 + 0x10000; + } + } + return first; + }; + if (Object.defineProperty) { + Object.defineProperty(String.prototype, 'codePointAt', { + value: codePointAt, + configurable: true, + writable: true, + }); + } else { + String.prototype.codePointAt = codePointAt; + } + })(); +} \ No newline at end of file diff --git a/polyfills/String/prototype/endsWith.js b/polyfills/String/prototype/endsWith.js new file mode 100644 index 0000000..afeb094 --- /dev/null +++ b/polyfills/String/prototype/endsWith.js @@ -0,0 +1,20 @@ +if (!String.prototype.endsWith) { + Object.defineProperty(String.prototype, 'endsWith', { + configurable: true, + writable: true, + value: 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; + }, + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/includes.js b/polyfills/String/prototype/includes.js new file mode 100644 index 0000000..cc6ff96 --- /dev/null +++ b/polyfills/String/prototype/includes.js @@ -0,0 +1,16 @@ +if (!String.prototype.includes) { + Object.defineProperty(String.prototype, 'includes', { + configurable: true, + writable: true, + value: function (search, start) { + if (typeof start !== 'number') { + start = 0; + } + if (start + search.length > this.length) { + return false; + } else { + return this.indexOf(search, start) !== -1; + } + }, + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/padEnd.js b/polyfills/String/prototype/padEnd.js new file mode 100644 index 0000000..655dc77 --- /dev/null +++ b/polyfills/String/prototype/padEnd.js @@ -0,0 +1,19 @@ +if (!String.prototype.padEnd) { + Object.defineProperty(String.prototype, 'padEnd', { + configurable: true, + writable: true, + value: function (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); + } + }, + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/padStart.js b/polyfills/String/prototype/padStart.js new file mode 100644 index 0000000..db0da64 --- /dev/null +++ b/polyfills/String/prototype/padStart.js @@ -0,0 +1,19 @@ +if (!String.prototype.padStart) { + Object.defineProperty(String.prototype, 'padStart', { + configurable: true, + writable: true, + value: function (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); + } + }, + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/repeat.js b/polyfills/String/prototype/repeat.js new file mode 100644 index 0000000..3d2df1f --- /dev/null +++ b/polyfills/String/prototype/repeat.js @@ -0,0 +1,43 @@ +if (!String.prototype.repeat) { + Object.defineProperty(String.prototype, 'repeat', { + configurable: true, + writable: true, + value: function (count) { + if (this == null) { + throw new TypeError("can't convert " + this + ' to object'); + } + var str = '' + this; + count = +count; + if (count != count) { + count = 0; + } + if (count < 0) { + throw new RangeError('repeat count must be non-negative'); + } + if (count == Infinity) { + throw new RangeError('repeat count must be less than infinity'); + } + count = Math.floor(count); + if (str.length == 0 || count == 0) { + return ''; + } + if (str.length * count >= 1 << 28) { + throw new RangeError( + 'repeat count must not overflow maximum string size' + ); + } + var rpt = ''; + for (; ;) { + if ((count & 1) == 1) { + rpt += str; + } + count >>>= 1; + if (count == 0) { + break; + } + str += str; + } + return rpt; + }, + }); +} \ No newline at end of file diff --git a/polyfills/String/prototype/startsWith.js b/polyfills/String/prototype/startsWith.js new file mode 100644 index 0000000..11d99c6 --- /dev/null +++ b/polyfills/String/prototype/startsWith.js @@ -0,0 +1,10 @@ +if (!String.prototype.startsWith) { + Object.defineProperty(String.prototype, 'startsWith', { + configurable: true, + writable: true, + value: function (searchString, position) { + position = position || 0; + return this.substr(position, searchString.length) === searchString; + }, + }); +} \ No newline at end of file diff --git a/test.html b/test.html index 37bfd9b..688c03f 100644 --- a/test.html +++ b/test.html @@ -18,7 +18,7 @@ body.innerHTML += "executing ['x','y','z'].item(-1) loads the polyfill
"; - var item = ['x','y','z'].item(-1); + var item = ['x','y','z'].at(-1); body.innerHTML += "result: "+item;