Skip to content

Commit

Permalink
fix: add Object.values polyfill for node <=6
Browse files Browse the repository at this point in the history
  • Loading branch information
straker committed Dec 14, 2023
1 parent f7b8d5e commit 16db935
Show file tree
Hide file tree
Showing 3 changed files with 328 additions and 321 deletions.
35 changes: 3 additions & 32 deletions lib/core/imports/index.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,16 @@
import './polyfills';

// some of these imports require polyfills to be loaded first
import { CssSelectorParser } from 'css-selector-parser';
import doT from '@deque/dot';
import emojiRegexText from 'emoji-regex';
import memoize from 'memoizee';
import Color from 'colorjs.io';

import es6promise from 'es6-promise';
import { Uint32Array } from 'typedarray';
import 'weakmap-polyfill';
import hasOwn from 'core-js-pure/actual/object/has-own';

if (!('hasOwn' in Object)) {
Object.hasOwn = hasOwn;
}

// prevent striping newline characters from strings (e.g. failure
// summaries). value must be synced with build/configure.js
doT.templateSettings.strip = false;

if (!('Promise' in window)) {
es6promise.polyfill();
}

if (!('Uint32Array' in window)) {
window.Uint32Array = Uint32Array;
}
if (window.Uint32Array) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some
if (!('some' in window.Uint32Array.prototype)) {
Object.defineProperty(window.Uint32Array.prototype, 'some', {
value: Array.prototype.some
});
}

if (!('reduce' in window.Uint32Array.prototype)) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce
Object.defineProperty(window.Uint32Array.prototype, 'reduce', {
value: Array.prototype.reduce
});
}
}

/**
* Namespace `axe.imports` which holds required external dependencies
*
Expand Down
325 changes: 325 additions & 0 deletions lib/core/imports/polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
import es6promise from 'es6-promise';
import { Uint32Array } from 'typedarray';
import 'weakmap-polyfill';
import hasOwn from 'core-js-pure/actual/object/has-own';
import values from 'core-js-pure/actual/object/values';

if (!('hasOwn' in Object)) {
Object.hasOwn = hasOwn;
}

if (!('values' in Object)) {
Object.values = values;
}

if (!('Promise' in window)) {
es6promise.polyfill();
}

if (!('Uint32Array' in window)) {
window.Uint32Array = Uint32Array;
}
if (window.Uint32Array) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some
if (!('some' in window.Uint32Array.prototype)) {
Object.defineProperty(window.Uint32Array.prototype, 'some', {
value: Array.prototype.some
});
}

if (!('reduce' in window.Uint32Array.prototype)) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce
Object.defineProperty(window.Uint32Array.prototype, 'reduce', {
value: Array.prototype.reduce
});
}
}

/*
These polyfills came directly from the ES Specification itself
Contained within:
- Object.assign
- Array.prototype.find
*/
if (typeof Object.assign !== 'function') {
(function () {
Object.assign = function (target) {
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}

var output = Object(target);
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index];
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};
})();
}

if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function (predicate) {
if (this === null) {
throw new TypeError('Array.prototype.find 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 value;
}
}
return undefined;
}
});
}

if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function (predicate, thisArg) {
if (this === null) {
throw new TypeError('Array.prototype.find 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 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.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function (searchElement) {
var O = Object(this);
var len = parseInt(O.length, 10) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1], 10) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {
k = 0;
}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (
searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)
) {
// NaN !== NaN
return true;
}
k++;
}
return false;
}
});
}

// Production steps of ECMA-262, Edition 5, 15.4.4.17
// Reference: http://es5.github.io/#x15.4.4.17
if (!Array.prototype.some) {
Object.defineProperty(Array.prototype, 'some', {
value: function (fun) {
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;

var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t && fun.call(thisArg, t[i], i, t)) {
return true;
}
}

return false;
}
});
}

if (!Array.from) {
Object.defineProperty(Array, 'from', {
value: (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;
};
})()
});
}

if (!String.prototype.includes) {
String.prototype.includes = function (search, start) {
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}

// @see https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat() {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);

return depth
? Array.prototype.reduce.call(
this,
function (acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}

return acc;
},
[]
)
: Array.prototype.slice.call(this);
},
writable: true
});
}

// linked from MDN docs on isConnected
// @see https://gist.github.com/eligrey/f109a6d0bf4efe3461201c3d7b745e8f
if (window.Node && !('isConnected' in window.Node.prototype)) {
Object.defineProperty(window.Node.prototype, 'isConnected', {
get() {
return (
!this.ownerDocument ||
!(
this.ownerDocument.compareDocumentPosition(this) &
this.DOCUMENT_POSITION_DISCONNECTED
)
);
}
});
}
Loading

0 comments on commit 16db935

Please sign in to comment.