react-proxy
Advanced tools
Comparing version
@@ -37,3 +37,3 @@ 'use strict'; | ||
var RESERVED_STATICS = ['length', 'name', 'arguments', 'caller', 'prototype', 'toString']; | ||
var RESERVED_STATICS = ['length', 'displayName', 'name', 'arguments', 'caller', 'prototype', 'toString']; | ||
@@ -81,10 +81,4 @@ function isEqualDescriptor(a, b) { | ||
var ProxyComponent = undefined; | ||
var savedDescriptors = {}; | ||
var staticDescriptors = {}; | ||
function wasStaticModifiedByUser(key) { | ||
// Compare the descriptor with the one we previously set ourselves. | ||
var currentDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
return !isEqualDescriptor(staticDescriptors[key], currentDescriptor); | ||
} | ||
function instantiate(factory, context, params) { | ||
@@ -140,2 +134,5 @@ var component = factory(); | ||
} | ||
if (NextComponent === CurrentComponent) { | ||
return; | ||
} | ||
@@ -149,2 +146,3 @@ // Prevent proxy cycles | ||
// Save the next constructor so we call it | ||
var PreviousComponent = CurrentComponent; | ||
CurrentComponent = NextComponent; | ||
@@ -158,3 +156,19 @@ | ||
// Copy static methods and properties | ||
// Copy over static methods and properties added at runtime | ||
if (PreviousComponent) { | ||
Object.getOwnPropertyNames(PreviousComponent).forEach(function (key) { | ||
if (RESERVED_STATICS.indexOf(key) > -1) { | ||
return; | ||
} | ||
var prevDescriptor = Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
var savedDescriptor = savedDescriptors[key]; | ||
if (!isEqualDescriptor(prevDescriptor, savedDescriptor)) { | ||
Object.defineProperty(NextComponent, key, prevDescriptor); | ||
} | ||
}); | ||
} | ||
// Copy newly defined static methods and properties | ||
Object.getOwnPropertyNames(NextComponent).forEach(function (key) { | ||
@@ -165,14 +179,25 @@ if (RESERVED_STATICS.indexOf(key) > -1) { | ||
var staticDescriptor = _extends({}, Object.getOwnPropertyDescriptor(NextComponent, key), { | ||
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
var savedDescriptor = savedDescriptors[key]; | ||
// Skip redefined descriptors | ||
if (prevDescriptor && savedDescriptor && !isEqualDescriptor(savedDescriptor, prevDescriptor)) { | ||
Object.defineProperty(NextComponent, key, prevDescriptor); | ||
Object.defineProperty(ProxyComponent, key, prevDescriptor); | ||
return; | ||
} | ||
if (prevDescriptor && !savedDescriptor) { | ||
Object.defineProperty(ProxyComponent, key, prevDescriptor); | ||
return; | ||
} | ||
var nextDescriptor = _extends({}, Object.getOwnPropertyDescriptor(NextComponent, key), { | ||
configurable: true | ||
}); | ||
// Copy static unless user has redefined it at runtime | ||
if (!wasStaticModifiedByUser(key)) { | ||
Object.defineProperty(ProxyComponent, key, staticDescriptor); | ||
staticDescriptors[key] = staticDescriptor; | ||
} | ||
savedDescriptors[key] = nextDescriptor; | ||
Object.defineProperty(ProxyComponent, key, nextDescriptor); | ||
}); | ||
// Remove old static methods and properties | ||
// Remove static methods and properties that are no longer defined | ||
Object.getOwnPropertyNames(ProxyComponent).forEach(function (key) { | ||
@@ -182,3 +207,2 @@ if (RESERVED_STATICS.indexOf(key) > -1) { | ||
} | ||
// Skip statics that exist on the next class | ||
@@ -188,14 +212,17 @@ if (NextComponent.hasOwnProperty(key)) { | ||
} | ||
// Skip non-configurable statics | ||
var descriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
if (descriptor && !descriptor.configurable) { | ||
var proxyDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
if (proxyDescriptor && !proxyDescriptor.configurable) { | ||
return; | ||
} | ||
// Delete static unless user has redefined it at runtime | ||
if (!wasStaticModifiedByUser(key)) { | ||
delete ProxyComponent[key]; | ||
delete staticDescriptors[key]; | ||
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
var savedDescriptor = savedDescriptors[key]; | ||
// Skip redefined descriptors | ||
if (prevDescriptor && savedDescriptor && !isEqualDescriptor(savedDescriptor, prevDescriptor)) { | ||
return; | ||
} | ||
delete ProxyComponent[key]; | ||
}); | ||
@@ -208,3 +235,3 @@ | ||
// Set up the constructor property so accessing the statics work | ||
ProxyComponent.prototype.constructor = ProxyComponent; | ||
ProxyComponent.prototype.constructor = NextComponent; | ||
@@ -211,0 +238,0 @@ // We might have added new methods that need to be auto-bound |
{ | ||
"name": "react-proxy", | ||
"version": "2.0.8", | ||
"version": "3.0.0-alpha.0", | ||
"description": "Proxies React components without unmounting or losing their state.", | ||
@@ -5,0 +5,0 @@ "main": "modules/index.js", |
@@ -86,2 +86,3 @@ # React Proxy [](https://travis-ci.org/gaearon/react-proxy) [](https://www.npmjs.com/package/react-proxy) | ||
* Replaces static properties unless they were overwritten by code | ||
* Sets up `this.constructor` to match the most recent class | ||
@@ -91,3 +92,2 @@ ## Known Limitations | ||
* Does not replace ES7 instance properties | ||
* Does not replace bound static methods | ||
* Replacing a method using [`autobind-decorator`](https://github.com/andreypopp/autobind-decorator) causes its identity to change | ||
@@ -94,0 +94,0 @@ |
@@ -9,2 +9,3 @@ import find from 'lodash/find'; | ||
'length', | ||
'displayName', | ||
'name', | ||
@@ -53,10 +54,4 @@ 'arguments', | ||
let ProxyComponent; | ||
let savedDescriptors = {}; | ||
let staticDescriptors = {}; | ||
function wasStaticModifiedByUser(key) { | ||
// Compare the descriptor with the one we previously set ourselves. | ||
const currentDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
return !isEqualDescriptor(staticDescriptors[key], currentDescriptor); | ||
} | ||
function instantiate(factory, context, params) { | ||
@@ -110,2 +105,5 @@ const component = factory(); | ||
} | ||
if (NextComponent === CurrentComponent) { | ||
return; | ||
} | ||
@@ -119,2 +117,3 @@ // Prevent proxy cycles | ||
// Save the next constructor so we call it | ||
const PreviousComponent = CurrentComponent; | ||
CurrentComponent = NextComponent; | ||
@@ -128,3 +127,19 @@ | ||
// Copy static methods and properties | ||
// Copy over static methods and properties added at runtime | ||
if (PreviousComponent) { | ||
Object.getOwnPropertyNames(PreviousComponent).forEach(key => { | ||
if (RESERVED_STATICS.indexOf(key) > -1) { | ||
return; | ||
} | ||
const prevDescriptor = Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
const savedDescriptor = savedDescriptors[key]; | ||
if (!isEqualDescriptor(prevDescriptor, savedDescriptor)) { | ||
Object.defineProperty(NextComponent, key, prevDescriptor); | ||
} | ||
}); | ||
} | ||
// Copy newly defined static methods and properties | ||
Object.getOwnPropertyNames(NextComponent).forEach(key => { | ||
@@ -135,15 +150,26 @@ if (RESERVED_STATICS.indexOf(key) > -1) { | ||
const staticDescriptor = { | ||
const prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
const savedDescriptor = savedDescriptors[key]; | ||
// Skip redefined descriptors | ||
if (prevDescriptor && savedDescriptor && !isEqualDescriptor(savedDescriptor, prevDescriptor)) { | ||
Object.defineProperty(NextComponent, key, prevDescriptor); | ||
Object.defineProperty(ProxyComponent, key, prevDescriptor); | ||
return; | ||
} | ||
if (prevDescriptor && !savedDescriptor) { | ||
Object.defineProperty(ProxyComponent, key, prevDescriptor); | ||
return; | ||
} | ||
const nextDescriptor = { | ||
...Object.getOwnPropertyDescriptor(NextComponent, key), | ||
configurable: true | ||
}; | ||
// Copy static unless user has redefined it at runtime | ||
if (!wasStaticModifiedByUser(key)) { | ||
Object.defineProperty(ProxyComponent, key, staticDescriptor); | ||
staticDescriptors[key] = staticDescriptor; | ||
} | ||
savedDescriptors[key] = nextDescriptor; | ||
Object.defineProperty(ProxyComponent, key, nextDescriptor); | ||
}); | ||
// Remove old static methods and properties | ||
// Remove static methods and properties that are no longer defined | ||
Object.getOwnPropertyNames(ProxyComponent).forEach(key => { | ||
@@ -153,3 +179,2 @@ if (RESERVED_STATICS.indexOf(key) > -1) { | ||
} | ||
// Skip statics that exist on the next class | ||
@@ -159,14 +184,17 @@ if (NextComponent.hasOwnProperty(key)) { | ||
} | ||
// Skip non-configurable statics | ||
const descriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
if (descriptor && !descriptor.configurable) { | ||
const proxyDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key); | ||
if (proxyDescriptor && !proxyDescriptor.configurable) { | ||
return; | ||
} | ||
// Delete static unless user has redefined it at runtime | ||
if (!wasStaticModifiedByUser(key)) { | ||
delete ProxyComponent[key]; | ||
delete staticDescriptors[key]; | ||
const prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key); | ||
const savedDescriptor = savedDescriptors[key]; | ||
// Skip redefined descriptors | ||
if (prevDescriptor && savedDescriptor && !isEqualDescriptor(savedDescriptor, prevDescriptor)) { | ||
return; | ||
} | ||
delete ProxyComponent[key]; | ||
}); | ||
@@ -179,3 +207,3 @@ | ||
// Set up the constructor property so accessing the statics work | ||
ProxyComponent.prototype.constructor = ProxyComponent; | ||
ProxyComponent.prototype.constructor = NextComponent; | ||
@@ -182,0 +210,0 @@ // We might have added new methods that need to be auto-bound |
Sorry, the diff of this file is too big to display
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
177120
1.91%5090
1.39%1
Infinity%