2020-12-21 12:39:53 +00:00
|
|
|
declare global {
|
|
|
|
interface Window {
|
2021-06-03 16:32:40 +00:00
|
|
|
Prototype?: {
|
|
|
|
Version?: string;
|
|
|
|
};
|
2020-12-21 12:39:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-20 15:06:50 +00:00
|
|
|
/**
|
|
|
|
* Polyfills the `Array.prototype.reduce` method.
|
|
|
|
*
|
|
|
|
* Production steps of ECMA-262, Edition 5, 15.4.4.21
|
|
|
|
* Reference: https://es5.github.io/#x15.4.4.21
|
|
|
|
* https://tc39.github.io/ecma262/#sec-array.prototype.reduce
|
|
|
|
*/
|
2021-04-30 19:59:59 +00:00
|
|
|
function polyfillArrayPrototypeReduce() {
|
2020-12-20 15:06:50 +00:00
|
|
|
Object.defineProperty(Array.prototype, "reduce", {
|
2021-04-30 19:59:59 +00:00
|
|
|
value(...args: unknown[]) {
|
2020-12-21 12:39:53 +00:00
|
|
|
if (
|
|
|
|
args.length === 0 &&
|
|
|
|
window.Prototype &&
|
|
|
|
window.Prototype.Version &&
|
|
|
|
window.Prototype.Version < "1.6.1"
|
|
|
|
) {
|
|
|
|
// Off-spec: compatibility with prototype.js
|
|
|
|
return this.length > 1 ? this : this[0];
|
|
|
|
}
|
|
|
|
|
2020-12-20 15:06:50 +00:00
|
|
|
const callback = args[0];
|
|
|
|
if (this === null) {
|
|
|
|
throw new TypeError(
|
2023-07-20 11:19:39 +00:00
|
|
|
"Array.prototype.reduce called on null or undefined",
|
2020-12-20 15:06:50 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
if (typeof callback !== "function") {
|
|
|
|
throw new TypeError(`${callback} is not a function`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const o = Object(this);
|
|
|
|
const len = o.length >>> 0;
|
|
|
|
let k = 0;
|
|
|
|
let value;
|
|
|
|
|
|
|
|
if (args.length >= 2) {
|
|
|
|
value = args[1];
|
|
|
|
} else {
|
|
|
|
while (k < len && !(k in o)) {
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
if (k >= len) {
|
|
|
|
throw new TypeError(
|
2023-07-20 11:19:39 +00:00
|
|
|
"Reduce of empty array with no initial value",
|
2020-12-20 15:06:50 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
value = o[k++];
|
|
|
|
}
|
|
|
|
|
|
|
|
while (k < len) {
|
|
|
|
if (k in o) {
|
|
|
|
value = callback(value, o[k], k, o);
|
|
|
|
}
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2020-12-30 19:41:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Polyfills the `Window` function.
|
|
|
|
*/
|
|
|
|
function polyfillWindow(): void {
|
|
|
|
if (
|
|
|
|
typeof window.constructor !== "function" ||
|
|
|
|
!isNativeFunction(window.constructor)
|
|
|
|
) {
|
|
|
|
// Don't polyfill `Window` if `window.constructor` has been overridden.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// @ts-expect-error: `Function not assignable to { new (): Window; prototype: Window; }`
|
|
|
|
window.Window = window.constructor;
|
|
|
|
}
|
|
|
|
|
2021-02-10 03:10:47 +00:00
|
|
|
/**
|
|
|
|
* Polyfills the `Reflect` object and members.
|
|
|
|
*
|
2022-11-13 13:45:14 +00:00
|
|
|
* This is a partial implementation, just enough to match our needs.
|
2021-02-10 03:10:47 +00:00
|
|
|
*/
|
|
|
|
function tryPolyfillReflect(): void {
|
2022-11-13 13:45:14 +00:00
|
|
|
if (window.Reflect === undefined || window.Reflect === null) {
|
2021-02-10 03:10:47 +00:00
|
|
|
// @ts-expect-error: {} indeed doesn't implement Reflect's interface.
|
|
|
|
window.Reflect = {};
|
|
|
|
}
|
|
|
|
if (typeof Reflect.get !== "function") {
|
|
|
|
Object.defineProperty(Reflect, "get", {
|
2021-04-30 19:59:59 +00:00
|
|
|
value<T>(target: T, key: keyof T) {
|
2021-02-10 03:10:47 +00:00
|
|
|
return target[key];
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (typeof Reflect.set !== "function") {
|
|
|
|
Object.defineProperty(Reflect, "set", {
|
2021-04-30 19:59:59 +00:00
|
|
|
value<T>(target: T, key: keyof T, value: T[keyof T]) {
|
2021-02-10 03:10:47 +00:00
|
|
|
target[key] = value;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2022-11-13 13:45:14 +00:00
|
|
|
if (typeof Reflect.has !== "function") {
|
|
|
|
Object.defineProperty(Reflect, "has", {
|
|
|
|
value<T>(target: T, key: keyof T) {
|
2022-12-13 21:36:44 +00:00
|
|
|
// @ts-expect-error: Type 'T' is not assignable to type 'object'.
|
2022-11-13 13:45:14 +00:00
|
|
|
return key in target;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (typeof Reflect.ownKeys !== "function") {
|
|
|
|
Object.defineProperty(Reflect, "ownKeys", {
|
|
|
|
value<T>(target: T) {
|
|
|
|
return [
|
|
|
|
...Object.getOwnPropertyNames(target),
|
|
|
|
...Object.getOwnPropertySymbols(target),
|
|
|
|
];
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
2021-02-10 03:10:47 +00:00
|
|
|
}
|
|
|
|
|
2020-12-30 19:41:34 +00:00
|
|
|
/**
|
|
|
|
* Determines whether a function is native or not.
|
|
|
|
*
|
|
|
|
* @param func The function to test.
|
|
|
|
* @returns True if the function hasn't been overridden.
|
|
|
|
*/
|
2021-04-30 19:59:59 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
2020-12-30 19:41:34 +00:00
|
|
|
function isNativeFunction(func: Function): boolean {
|
|
|
|
const val =
|
|
|
|
typeof Function.prototype.toString === "function"
|
|
|
|
? Function.prototype.toString()
|
|
|
|
: null;
|
|
|
|
if (typeof val === "string" && val.indexOf("[native code]") >= 0) {
|
|
|
|
return (
|
|
|
|
Function.prototype.toString.call(func).indexOf("[native code]") >= 0
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks and applies the polyfills to the current window, if needed.
|
|
|
|
*/
|
|
|
|
export function setPolyfillsOnLoad(): void {
|
|
|
|
if (
|
|
|
|
typeof Array.prototype.reduce !== "function" ||
|
|
|
|
!isNativeFunction(Array.prototype.reduce)
|
|
|
|
) {
|
|
|
|
// Some external libraries override the `Array.prototype.reduce` method in a way
|
|
|
|
// that causes Webpack to crash (#1507, #1865), so we need to override it again.
|
|
|
|
polyfillArrayPrototypeReduce();
|
|
|
|
}
|
|
|
|
if (typeof Window !== "function" || !isNativeFunction(Window)) {
|
|
|
|
// Overriding the native `Window` function causes issues in wasm-bindgen, as a
|
|
|
|
// code like `window instanceof Window` will no longer work.
|
|
|
|
polyfillWindow();
|
|
|
|
}
|
2022-11-13 13:45:14 +00:00
|
|
|
// Some pages override the native `Reflect` object, which causes various issues:
|
|
|
|
// 1- wasm-bindgen's stdlib may crash (#3173).
|
|
|
|
// 2- FlashVars may be ignored (#8537).
|
2021-02-10 03:10:47 +00:00
|
|
|
tryPolyfillReflect();
|
2020-12-30 19:41:34 +00:00
|
|
|
}
|