Skip to content

Commit

Permalink
Respect original enumerability/writability when polyfilling globals
Browse files Browse the repository at this point in the history
Summary:
Reuses the original property descriptor when overwriting / polyfilling globals to ensure enumerability and writability are the same
Closes #7704

Differential Revision: D3338119

Pulled By: davidaurelio

fbshipit-source-id: ab456324a3346cd3ec8b2c3e3a2378408c92087c
  • Loading branch information
davidaurelio authored and Facebook Github Bot 6 committed May 24, 2016
1 parent 6629ae9 commit 3d8725d
Showing 1 changed file with 33 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,40 +64,47 @@ function setUpConsole() {
* https://github.com/facebook/react-native/issues/934
*/
function polyfillGlobal(name, newValue, scope = global) {
const descriptor = Object.getOwnPropertyDescriptor(scope, name) || {
// jest for some bad reasons runs the polyfill code multiple times. In jest
// environment, XmlHttpRequest doesn't exist so getOwnPropertyDescriptor
// returns undefined and defineProperty default for writable is false.
// Therefore, the second time it runs, defineProperty will fatal :(
writable: true,
};

if (scope[name] !== undefined) {
const descriptor = Object.getOwnPropertyDescriptor(scope, name);
if (descriptor) {
const backupName = `original${name[0].toUpperCase()}${name.substr(1)}`;
Object.defineProperty(scope, backupName, {...descriptor, value: scope[name]});
}

Object.defineProperty(scope, name, {...descriptor, value: newValue});
const {enumerable, writable} = descriptor || {};

// jest for some bad reasons runs the polyfill code multiple times. In jest
// environment, XmlHttpRequest doesn't exist so getOwnPropertyDescriptor
// returns undefined and defineProperty default for writable is false.
// Therefore, the second time it runs, defineProperty will fatal :(

Object.defineProperty(scope, name, {
configurable: true,
enumerable: enumerable !== false,
writable: writable !== false,
value: newValue,
});
}

function polyfillLazyGlobal(name, valueFn, scope = global) {
if (scope[name] !== undefined) {
const descriptor = Object.getOwnPropertyDescriptor(scope, name);
const descriptor = getPropertyDescriptor(scope, name);
if (descriptor) {
const backupName = `original${name[0].toUpperCase()}${name.substr(1)}`;
Object.defineProperty(scope, backupName, {...descriptor, value: scope[name]});
Object.defineProperty(scope, backupName, descriptor);
}

const {enumerable, writable} = descriptor || {};
Object.defineProperty(scope, name, {
configurable: true,
enumerable: true,
enumerable: enumerable !== false,
get() {
return (this[name] = valueFn());
},
set(value) {
Object.defineProperty(this, name, {
configurable: true,
enumerable: true,
value
enumerable: enumerable !== false,
writable: writable !== false,
value,
});
}
});
Expand Down Expand Up @@ -211,6 +218,16 @@ function setUpDevTools() {
}
}

function getPropertyDescriptor(object, name) {
while (object) {
const descriptor = Object.getOwnPropertyDescriptor(object, name);
if (descriptor) {
return descriptor;
}
object = Object.getPrototypeOf(object);
}
}

setUpProcess();
setUpConsole();
setUpTimers();
Expand Down

0 comments on commit 3d8725d

Please sign in to comment.