1777 lines
54 KiB
JavaScript
1777 lines
54 KiB
JavaScript
|
|
'use strict';
|
|||
|
|
|
|||
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|||
|
|
|
|||
|
|
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|||
|
|
|
|||
|
|
var React = require('react');
|
|||
|
|
var React__default = _interopDefault(React);
|
|||
|
|
var shallowEqual = _interopDefault(require('shallowequal'));
|
|||
|
|
var levenshtein = _interopDefault(require('fast-levenshtein'));
|
|||
|
|
var PropTypes = _interopDefault(require('prop-types'));
|
|||
|
|
var defaultPolyfill = require('react-lifecycles-compat');
|
|||
|
|
var defaultPolyfill__default = _interopDefault(defaultPolyfill);
|
|||
|
|
var hoistNonReactStatic = _interopDefault(require('hoist-non-react-statics'));
|
|||
|
|
|
|||
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
|
|||
|
|
return typeof obj;
|
|||
|
|
} : function (obj) {
|
|||
|
|
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var classCallCheck = function (instance, Constructor) {
|
|||
|
|
if (!(instance instanceof Constructor)) {
|
|||
|
|
throw new TypeError("Cannot call a class as a function");
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _extends = Object.assign || function (target) {
|
|||
|
|
for (var i = 1; i < arguments.length; i++) {
|
|||
|
|
var source = arguments[i];
|
|||
|
|
|
|||
|
|
for (var key in source) {
|
|||
|
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|||
|
|
target[key] = source[key];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var inherits = function (subClass, superClass) {
|
|||
|
|
if (typeof superClass !== "function" && superClass !== null) {
|
|||
|
|
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|||
|
|
constructor: {
|
|||
|
|
value: subClass,
|
|||
|
|
enumerable: false,
|
|||
|
|
writable: true,
|
|||
|
|
configurable: true
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var possibleConstructorReturn = function (self, call) {
|
|||
|
|
if (!self) {
|
|||
|
|
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-underscore-dangle */
|
|||
|
|
|
|||
|
|
var isCompositeComponent = function isCompositeComponent(type) {
|
|||
|
|
return typeof type === 'function';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getComponentDisplayName = function getComponentDisplayName(type) {
|
|||
|
|
var displayName = type.displayName || type.name;
|
|||
|
|
return displayName && displayName !== 'ReactComponent' ? displayName : 'Component';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var reactLifeCycleMountMethods = ['componentWillMount', 'componentDidMount'];
|
|||
|
|
|
|||
|
|
function isReactClass(Component) {
|
|||
|
|
return !!(Component.prototype && (React__default.Component.prototype.isPrototypeOf(Component.prototype) ||
|
|||
|
|
// react 14 support
|
|||
|
|
Component.prototype.isReactComponent || Component.prototype.componentWillMount || Component.prototype.componentWillUnmount || Component.prototype.componentDidMount || Component.prototype.componentDidUnmount || Component.prototype.render));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isReactClassInstance(Component) {
|
|||
|
|
return Component && isReactClass({ prototype: Object.getPrototypeOf(Component) });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var getInternalInstance = function getInternalInstance(instance) {
|
|||
|
|
return instance._reactInternalFiber || // React 16
|
|||
|
|
instance._reactInternalInstance || // React 15
|
|||
|
|
null;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var updateInstance = function updateInstance(instance) {
|
|||
|
|
var updater = instance.updater,
|
|||
|
|
forceUpdate = instance.forceUpdate;
|
|||
|
|
|
|||
|
|
if (typeof forceUpdate === 'function') {
|
|||
|
|
instance.forceUpdate();
|
|||
|
|
} else if (updater && typeof updater.enqueueForceUpdate === 'function') {
|
|||
|
|
updater.enqueueForceUpdate(instance);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var isFragmentNode = function isFragmentNode(_ref) {
|
|||
|
|
var type = _ref.type;
|
|||
|
|
return React__default.Fragment && type === React__default.Fragment;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var ContextType = React__default.createContext ? React__default.createContext() : null;
|
|||
|
|
var ConsumerType = ContextType && ContextType.Consumer.$$typeof;
|
|||
|
|
var ProviderType = ContextType && ContextType.Provider.$$typeof;
|
|||
|
|
|
|||
|
|
var CONTEXT_CURRENT_VALUE = '_currentValue';
|
|||
|
|
|
|||
|
|
var isContextConsumer = function isContextConsumer(_ref2) {
|
|||
|
|
var type = _ref2.type;
|
|||
|
|
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && type.$$typeof === ConsumerType;
|
|||
|
|
};
|
|||
|
|
var isContextProvider = function isContextProvider(_ref3) {
|
|||
|
|
var type = _ref3.type;
|
|||
|
|
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && type.$$typeof === ProviderType;
|
|||
|
|
};
|
|||
|
|
var getContextProvider = function getContextProvider(type) {
|
|||
|
|
return type && type._context;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var generation = 1;
|
|||
|
|
|
|||
|
|
var increment = function increment() {
|
|||
|
|
return generation++;
|
|||
|
|
};
|
|||
|
|
var get$1 = function get() {
|
|||
|
|
return generation;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var PREFIX = '__reactstandin__';
|
|||
|
|
var PROXY_KEY = PREFIX + 'key';
|
|||
|
|
var GENERATION = PREFIX + 'proxyGeneration';
|
|||
|
|
var REGENERATE_METHOD = PREFIX + 'regenerateByEval';
|
|||
|
|
var UNWRAP_PROXY = PREFIX + 'getCurrent';
|
|||
|
|
var CACHED_RESULT = PREFIX + 'cachedResult';
|
|||
|
|
var PROXY_IS_MOUNTED = PREFIX + 'isMounted';
|
|||
|
|
|
|||
|
|
var configuration = {
|
|||
|
|
// Log level
|
|||
|
|
logLevel: 'error',
|
|||
|
|
|
|||
|
|
// Allows using SFC without changes. leading to some components not updated
|
|||
|
|
pureSFC: false,
|
|||
|
|
|
|||
|
|
// Allows SFC to be used, enables "intermediate" components used by Relay, should be disabled for Preact
|
|||
|
|
allowSFC: true,
|
|||
|
|
|
|||
|
|
// Hook on babel component register.
|
|||
|
|
onComponentRegister: false
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-console */
|
|||
|
|
|
|||
|
|
var logger = {
|
|||
|
|
debug: function debug() {
|
|||
|
|
if (['debug'].indexOf(configuration.logLevel) !== -1) {
|
|||
|
|
var _console;
|
|||
|
|
|
|||
|
|
(_console = console).debug.apply(_console, arguments);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
log: function log() {
|
|||
|
|
if (['debug', 'log'].indexOf(configuration.logLevel) !== -1) {
|
|||
|
|
var _console2;
|
|||
|
|
|
|||
|
|
(_console2 = console).log.apply(_console2, arguments);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
warn: function warn() {
|
|||
|
|
if (['debug', 'log', 'warn'].indexOf(configuration.logLevel) !== -1) {
|
|||
|
|
var _console3;
|
|||
|
|
|
|||
|
|
(_console3 = console).warn.apply(_console3, arguments);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
error: function error() {
|
|||
|
|
if (['debug', 'log', 'warn', 'error'].indexOf(configuration.logLevel) !== -1) {
|
|||
|
|
var _console4;
|
|||
|
|
|
|||
|
|
(_console4 = console).error.apply(_console4, arguments);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-eval, func-names */
|
|||
|
|
|
|||
|
|
function safeReactConstructor(Component, lastInstance) {
|
|||
|
|
try {
|
|||
|
|
if (lastInstance) {
|
|||
|
|
return new Component(lastInstance.props, lastInstance.context);
|
|||
|
|
}
|
|||
|
|
return new Component({}, {});
|
|||
|
|
} catch (e) {
|
|||
|
|
// some components, like Redux connect could not be created without proper context
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isNativeFunction(fn) {
|
|||
|
|
return typeof fn === 'function' ? fn.toString().indexOf('[native code]') > 0 : false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var identity = function identity(a) {
|
|||
|
|
return a;
|
|||
|
|
};
|
|||
|
|
var indirectEval = eval;
|
|||
|
|
|
|||
|
|
var doesSupportClasses = function () {
|
|||
|
|
try {
|
|||
|
|
indirectEval('class Test {}');
|
|||
|
|
return true;
|
|||
|
|
} catch (e) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}();
|
|||
|
|
|
|||
|
|
var ES6ProxyComponentFactory = doesSupportClasses && indirectEval('\n(function(InitialParent, postConstructionAction) {\n return class ProxyComponent extends InitialParent {\n constructor(props, context) {\n super(props, context)\n postConstructionAction.call(this)\n }\n }\n})\n');
|
|||
|
|
|
|||
|
|
var ES5ProxyComponentFactory = function ES5ProxyComponentFactory(InitialParent, postConstructionAction) {
|
|||
|
|
function ProxyComponent(props, context) {
|
|||
|
|
InitialParent.call(this, props, context);
|
|||
|
|
postConstructionAction.call(this);
|
|||
|
|
}
|
|||
|
|
ProxyComponent.prototype = Object.create(InitialParent.prototype);
|
|||
|
|
Object.setPrototypeOf(ProxyComponent, InitialParent);
|
|||
|
|
return ProxyComponent;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var proxyClassCreator = doesSupportClasses ? ES6ProxyComponentFactory : ES5ProxyComponentFactory;
|
|||
|
|
|
|||
|
|
function getOwnKeys(target) {
|
|||
|
|
return [].concat(Object.getOwnPropertyNames(target), Object.getOwnPropertySymbols(target));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function shallowStringsEqual(a, b) {
|
|||
|
|
for (var key in a) {
|
|||
|
|
if (String(a[key]) !== String(b[key])) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function deepPrototypeUpdate(dest, source) {
|
|||
|
|
var deepDest = Object.getPrototypeOf(dest);
|
|||
|
|
var deepSrc = Object.getPrototypeOf(source);
|
|||
|
|
if (deepDest && deepSrc && deepSrc !== deepDest) {
|
|||
|
|
deepPrototypeUpdate(deepDest, deepSrc);
|
|||
|
|
}
|
|||
|
|
if (source.prototype && source.prototype !== dest.prototype) {
|
|||
|
|
dest.prototype = source.prototype;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function safeDefineProperty(target, key, props) {
|
|||
|
|
try {
|
|||
|
|
Object.defineProperty(target, key, props);
|
|||
|
|
} catch (e) {
|
|||
|
|
logger.warn('Error while wrapping', key, ' -> ', e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var RESERVED_STATICS = ['length', 'displayName', 'name', 'arguments', 'caller', 'prototype', 'toString', 'valueOf', 'isStatelessFunctionalProxy', PROXY_KEY, UNWRAP_PROXY];
|
|||
|
|
|
|||
|
|
function transferStaticProps(ProxyComponent, savedDescriptors, PreviousComponent, NextComponent) {
|
|||
|
|
Object.getOwnPropertyNames(ProxyComponent).forEach(function (key) {
|
|||
|
|
if (RESERVED_STATICS.indexOf(key) !== -1) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var prevDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key);
|
|||
|
|
var savedDescriptor = savedDescriptors[key];
|
|||
|
|
|
|||
|
|
if (!shallowEqual(prevDescriptor, savedDescriptor)) {
|
|||
|
|
safeDefineProperty(NextComponent, key, prevDescriptor);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Copy newly defined static methods and properties
|
|||
|
|
Object.getOwnPropertyNames(NextComponent).forEach(function (key) {
|
|||
|
|
if (RESERVED_STATICS.indexOf(key) !== -1) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(ProxyComponent, key);
|
|||
|
|
var savedDescriptor = savedDescriptors[key];
|
|||
|
|
|
|||
|
|
// Skip redefined descriptors
|
|||
|
|
if (prevDescriptor && savedDescriptor && !shallowEqual(savedDescriptor, prevDescriptor)) {
|
|||
|
|
safeDefineProperty(NextComponent, key, prevDescriptor);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (prevDescriptor && !savedDescriptor) {
|
|||
|
|
safeDefineProperty(ProxyComponent, key, prevDescriptor);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var nextDescriptor = _extends({}, Object.getOwnPropertyDescriptor(NextComponent, key), {
|
|||
|
|
configurable: true
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
savedDescriptors[key] = nextDescriptor;
|
|||
|
|
safeDefineProperty(ProxyComponent, key, nextDescriptor);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Remove static methods and properties that are no longer defined
|
|||
|
|
Object.getOwnPropertyNames(ProxyComponent).forEach(function (key) {
|
|||
|
|
if (RESERVED_STATICS.indexOf(key) !== -1) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// Skip statics that exist on the next class
|
|||
|
|
if (NextComponent.hasOwnProperty(key)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// Skip non-configurable statics
|
|||
|
|
var proxyDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key);
|
|||
|
|
if (proxyDescriptor && !proxyDescriptor.configurable) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key);
|
|||
|
|
var savedDescriptor = savedDescriptors[key];
|
|||
|
|
|
|||
|
|
// Skip redefined descriptors
|
|||
|
|
if (prevDescriptor && savedDescriptor && !shallowEqual(savedDescriptor, prevDescriptor)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
safeDefineProperty(ProxyComponent, key, {
|
|||
|
|
value: undefined
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return savedDescriptors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function mergeComponents(ProxyComponent, NextComponent, InitialComponent, lastInstance, injectedMembers) {
|
|||
|
|
var injectedCode = {};
|
|||
|
|
try {
|
|||
|
|
var nextInstance = safeReactConstructor(NextComponent, lastInstance);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Bypass babel class inheritance checking
|
|||
|
|
deepPrototypeUpdate(InitialComponent, NextComponent);
|
|||
|
|
} catch (e) {
|
|||
|
|
// It was ES6 class
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var proxyInstance = safeReactConstructor(ProxyComponent, lastInstance);
|
|||
|
|
|
|||
|
|
if (!nextInstance || !proxyInstance) {
|
|||
|
|
return injectedCode;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var mergedAttrs = _extends({}, proxyInstance, nextInstance);
|
|||
|
|
var hasRegenerate = proxyInstance[REGENERATE_METHOD];
|
|||
|
|
var ownKeys = getOwnKeys(Object.getPrototypeOf(ProxyComponent.prototype));
|
|||
|
|
Object.keys(mergedAttrs).forEach(function (key) {
|
|||
|
|
if (key.startsWith(PREFIX)) return;
|
|||
|
|
var nextAttr = nextInstance[key];
|
|||
|
|
var prevAttr = proxyInstance[key];
|
|||
|
|
if (nextAttr) {
|
|||
|
|
if (isNativeFunction(nextAttr) || isNativeFunction(prevAttr)) {
|
|||
|
|
// this is bound method
|
|||
|
|
var isSameArity = nextAttr.length === prevAttr.length;
|
|||
|
|
var existsInPrototype = ownKeys.indexOf(key) >= 0 || ProxyComponent.prototype[key];
|
|||
|
|
if ((isSameArity || !prevAttr) && existsInPrototype) {
|
|||
|
|
if (hasRegenerate) {
|
|||
|
|
injectedCode[key] = 'Object.getPrototypeOf(this)[\'' + key + '\'].bind(this)';
|
|||
|
|
} else {
|
|||
|
|
logger.warn('React Hot Loader:,', 'Non-controlled class', ProxyComponent.name, 'contains a new native or bound function ', key, nextAttr, '. Unable to reproduce');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
logger.warn('React Hot Loader:', 'Updated class ', ProxyComponent.name, 'contains native or bound function ', key, nextAttr, '. Unable to reproduce, use arrow functions instead.', '(arity: ' + nextAttr.length + '/' + prevAttr.length + ', proto: ' + (existsInPrototype ? 'yes' : 'no'));
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var nextString = String(nextAttr);
|
|||
|
|
var injectedBefore = injectedMembers[key];
|
|||
|
|
var isArrow = nextString.indexOf('=>') >= 0;
|
|||
|
|
var isFunction = nextString.indexOf('function') >= 0 || isArrow;
|
|||
|
|
var referToThis = nextString.indexOf('this') >= 0;
|
|||
|
|
if (nextString !== String(prevAttr) || injectedBefore && nextString !== String(injectedBefore) || isArrow && referToThis) {
|
|||
|
|
if (!hasRegenerate) {
|
|||
|
|
if (!isFunction) {
|
|||
|
|
// just copy prop over
|
|||
|
|
injectedCode[key] = nextAttr;
|
|||
|
|
} else {
|
|||
|
|
logger.warn('React Hot Loader:', ' Updated class ', ProxyComponent.name, 'had different code for', key, nextAttr, '. Unable to reproduce. Regeneration support needed.');
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
injectedCode[key] = nextAttr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} catch (e) {
|
|||
|
|
logger.warn('React Hot Loader:', e);
|
|||
|
|
}
|
|||
|
|
return injectedCode;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function checkLifeCycleMethods(ProxyComponent, NextComponent) {
|
|||
|
|
try {
|
|||
|
|
var p1 = Object.getPrototypeOf(ProxyComponent.prototype);
|
|||
|
|
var p2 = NextComponent.prototype;
|
|||
|
|
reactLifeCycleMountMethods.forEach(function (key) {
|
|||
|
|
var d1 = Object.getOwnPropertyDescriptor(p1, key) || { value: p1[key] };
|
|||
|
|
var d2 = Object.getOwnPropertyDescriptor(p2, key) || { value: p2[key] };
|
|||
|
|
if (!shallowStringsEqual(d1, d2)) {
|
|||
|
|
logger.warn('React Hot Loader:', 'You did update', ProxyComponent.name, 's lifecycle method', key, '. Unable to repeat');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} catch (e) {
|
|||
|
|
// Ignore errors
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function inject(target, currentGeneration, injectedMembers) {
|
|||
|
|
if (target[GENERATION] !== currentGeneration) {
|
|||
|
|
var hasRegenerate = !!target[REGENERATE_METHOD];
|
|||
|
|
Object.keys(injectedMembers).forEach(function (key) {
|
|||
|
|
try {
|
|||
|
|
if (hasRegenerate) {
|
|||
|
|
var usedThis = String(injectedMembers[key]).match(/_this([\d]+)/gi) || [];
|
|||
|
|
target[REGENERATE_METHOD](key, '(function REACT_HOT_LOADER_SANDBOX () {\n var _this = this; // common babel transpile\n ' + usedThis.map(function (name) {
|
|||
|
|
return 'var ' + name + ' = this;';
|
|||
|
|
}) + '\n\n return ' + injectedMembers[key] + ';\n }).call(this)');
|
|||
|
|
} else {
|
|||
|
|
target[key] = injectedMembers[key];
|
|||
|
|
}
|
|||
|
|
} catch (e) {
|
|||
|
|
logger.warn('React Hot Loader: Failed to regenerate method ', key, ' of class ', target);
|
|||
|
|
logger.warn('got error', e);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
target[GENERATION] = currentGeneration;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var has = Object.prototype.hasOwnProperty;
|
|||
|
|
|
|||
|
|
var proxies = new WeakMap();
|
|||
|
|
|
|||
|
|
var resetClassProxies = function resetClassProxies() {
|
|||
|
|
proxies = new WeakMap();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var blackListedClassMembers = ['constructor', 'render', 'componentWillMount', 'componentDidMount', 'componentWillReceiveProps', 'componentWillUnmount', 'hotComponentRender', 'getInitialState', 'getDefaultProps'];
|
|||
|
|
|
|||
|
|
var defaultRenderOptions = {
|
|||
|
|
componentWillRender: identity,
|
|||
|
|
componentDidUpdate: function componentDidUpdate(result) {
|
|||
|
|
return result;
|
|||
|
|
},
|
|||
|
|
componentDidRender: function componentDidRender(result) {
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var defineClassMember = function defineClassMember(Class, methodName, methodBody) {
|
|||
|
|
return safeDefineProperty(Class.prototype, methodName, {
|
|||
|
|
configurable: true,
|
|||
|
|
writable: true,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: methodBody
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var defineClassMembers = function defineClassMembers(Class, methods) {
|
|||
|
|
return Object.keys(methods).forEach(function (methodName) {
|
|||
|
|
return defineClassMember(Class, methodName, methods[methodName]);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var setSFPFlag = function setSFPFlag(component, flag) {
|
|||
|
|
return safeDefineProperty(component, 'isStatelessFunctionalProxy', {
|
|||
|
|
configurable: false,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: flag
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var copyMethodDescriptors = function copyMethodDescriptors(target, source) {
|
|||
|
|
if (source) {
|
|||
|
|
// it is possible to use `function-double` to construct an ideal clone, but does not make a sence
|
|||
|
|
var keys = Object.getOwnPropertyNames(source);
|
|||
|
|
|
|||
|
|
keys.forEach(function (key) {
|
|||
|
|
return safeDefineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
safeDefineProperty(target, 'toString', {
|
|||
|
|
configurable: true,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: function toString() {
|
|||
|
|
return String(source);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return target;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function createClassProxy(InitialComponent, proxyKey, options) {
|
|||
|
|
var renderOptions = _extends({}, defaultRenderOptions, options);
|
|||
|
|
// Prevent double wrapping.
|
|||
|
|
// Given a proxy class, return the existing proxy managing it.
|
|||
|
|
var existingProxy = proxies.get(InitialComponent);
|
|||
|
|
|
|||
|
|
if (existingProxy) {
|
|||
|
|
return existingProxy;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var CurrentComponent = void 0;
|
|||
|
|
var savedDescriptors = {};
|
|||
|
|
var injectedMembers = {};
|
|||
|
|
var proxyGeneration = 0;
|
|||
|
|
var classUpdatePostponed = null;
|
|||
|
|
var instancesCount = 0;
|
|||
|
|
var isFunctionalComponent = !isReactClass(InitialComponent);
|
|||
|
|
|
|||
|
|
var lastInstance = null;
|
|||
|
|
|
|||
|
|
function postConstructionAction() {
|
|||
|
|
this[GENERATION] = 0;
|
|||
|
|
|
|||
|
|
lastInstance = this;
|
|||
|
|
// is there is an update pending
|
|||
|
|
if (classUpdatePostponed) {
|
|||
|
|
var callUpdate = classUpdatePostponed;
|
|||
|
|
classUpdatePostponed = null;
|
|||
|
|
callUpdate();
|
|||
|
|
}
|
|||
|
|
// As long we can't override constructor
|
|||
|
|
// every class shall evolve from a base class
|
|||
|
|
inject(this, proxyGeneration, injectedMembers);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function proxiedUpdate() {
|
|||
|
|
if (this) {
|
|||
|
|
inject(this, proxyGeneration, injectedMembers);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function lifeCycleWrapperFactory(wrapperName) {
|
|||
|
|
var sideEffect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity;
|
|||
|
|
|
|||
|
|
return copyMethodDescriptors(function wrappedMethod() {
|
|||
|
|
proxiedUpdate.call(this);
|
|||
|
|
sideEffect(this);
|
|||
|
|
|
|||
|
|
for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
rest[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return !isFunctionalComponent && CurrentComponent.prototype[wrapperName] && CurrentComponent.prototype[wrapperName].apply(this, rest);
|
|||
|
|
}, InitialComponent.prototype && InitialComponent.prototype[wrapperName]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function methodWrapperFactory(wrapperName, realMethod) {
|
|||
|
|
return copyMethodDescriptors(function wrappedMethod() {
|
|||
|
|
for (var _len2 = arguments.length, rest = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|||
|
|
rest[_key2] = arguments[_key2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return realMethod.apply(this, rest);
|
|||
|
|
}, realMethod);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var fakeBasePrototype = function fakeBasePrototype(Base) {
|
|||
|
|
return Object.getOwnPropertyNames(Base).filter(function (key) {
|
|||
|
|
return blackListedClassMembers.indexOf(key) === -1;
|
|||
|
|
}).filter(function (key) {
|
|||
|
|
var descriptor = Object.getOwnPropertyDescriptor(Base, key);
|
|||
|
|
return typeof descriptor.value === 'function';
|
|||
|
|
}).reduce(function (acc, key) {
|
|||
|
|
acc[key] = methodWrapperFactory(key, Base[key]);
|
|||
|
|
return acc;
|
|||
|
|
}, {});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var componentDidMount = lifeCycleWrapperFactory('componentDidMount', function (target) {
|
|||
|
|
target[PROXY_IS_MOUNTED] = true;
|
|||
|
|
instancesCount++;
|
|||
|
|
});
|
|||
|
|
var componentDidUpdate = lifeCycleWrapperFactory('componentDidUpdate', renderOptions.componentDidUpdate);
|
|||
|
|
var componentWillUnmount = lifeCycleWrapperFactory('componentWillUnmount', function (target) {
|
|||
|
|
target[PROXY_IS_MOUNTED] = false;
|
|||
|
|
instancesCount--;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function hotComponentRender() {
|
|||
|
|
// repeating subrender call to keep RENDERED_GENERATION up to date
|
|||
|
|
renderOptions.componentWillRender(this);
|
|||
|
|
proxiedUpdate.call(this);
|
|||
|
|
var result = void 0;
|
|||
|
|
|
|||
|
|
// We need to use hasOwnProperty here, as the cached result is a React node
|
|||
|
|
// and can be null or some other falsy value.
|
|||
|
|
if (has.call(this, CACHED_RESULT)) {
|
|||
|
|
result = this[CACHED_RESULT];
|
|||
|
|
delete this[CACHED_RESULT];
|
|||
|
|
} else if (isFunctionalComponent) {
|
|||
|
|
result = CurrentComponent(this.props, this.context);
|
|||
|
|
} else {
|
|||
|
|
result = (CurrentComponent.prototype.render || this.render).apply(this,
|
|||
|
|
// eslint-disable-next-line prefer-rest-params
|
|||
|
|
arguments);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return renderOptions.componentDidRender.call(this, result);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function proxiedRender() {
|
|||
|
|
renderOptions.componentWillRender(this);
|
|||
|
|
|
|||
|
|
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|||
|
|
args[_key3] = arguments[_key3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return hotComponentRender.call.apply(hotComponentRender, [this].concat(args));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var defineProxyMethods = function defineProxyMethods(Proxy) {
|
|||
|
|
var Base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|||
|
|
|
|||
|
|
defineClassMembers(Proxy, _extends({}, fakeBasePrototype(Base), {
|
|||
|
|
render: proxiedRender,
|
|||
|
|
hotComponentRender: hotComponentRender,
|
|||
|
|
componentDidMount: componentDidMount,
|
|||
|
|
componentDidUpdate: componentDidUpdate,
|
|||
|
|
componentWillUnmount: componentWillUnmount
|
|||
|
|
}));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var _ProxyFacade = void 0;
|
|||
|
|
var ProxyComponent = null;
|
|||
|
|
var proxy = void 0;
|
|||
|
|
|
|||
|
|
if (!isFunctionalComponent) {
|
|||
|
|
// Component
|
|||
|
|
ProxyComponent = proxyClassCreator(InitialComponent, postConstructionAction);
|
|||
|
|
|
|||
|
|
defineProxyMethods(ProxyComponent, InitialComponent.prototype);
|
|||
|
|
|
|||
|
|
_ProxyFacade = ProxyComponent;
|
|||
|
|
} else if (!configuration.allowSFC) {
|
|||
|
|
// SFC Converted to component. Does not support returning precreated instances from render.
|
|||
|
|
ProxyComponent = proxyClassCreator(React.Component, postConstructionAction);
|
|||
|
|
|
|||
|
|
defineProxyMethods(ProxyComponent);
|
|||
|
|
_ProxyFacade = ProxyComponent;
|
|||
|
|
} else {
|
|||
|
|
// SFC
|
|||
|
|
|
|||
|
|
// This function only gets called for the initial mount. The actual
|
|||
|
|
// rendered component instance will be the return value.
|
|||
|
|
|
|||
|
|
// eslint-disable-next-line func-names
|
|||
|
|
_ProxyFacade = function ProxyFacade(props, context) {
|
|||
|
|
var result = CurrentComponent(props, context);
|
|||
|
|
|
|||
|
|
// simple SFC, could continue to be SFC
|
|||
|
|
if (configuration.pureSFC) {
|
|||
|
|
if (!CurrentComponent.contextTypes) {
|
|||
|
|
if (!_ProxyFacade.isStatelessFunctionalProxy) {
|
|||
|
|
setSFPFlag(_ProxyFacade, true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return renderOptions.componentDidRender(result);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
setSFPFlag(_ProxyFacade, false);
|
|||
|
|
|
|||
|
|
// This is a Relay-style container constructor. We can't do the prototype-
|
|||
|
|
// style wrapping for this as we do elsewhere, so just we just pass it
|
|||
|
|
// through as-is.
|
|||
|
|
if (isReactClassInstance(result)) {
|
|||
|
|
ProxyComponent = null;
|
|||
|
|
|
|||
|
|
// Relay lazily sets statics like getDerivedStateFromProps on initial
|
|||
|
|
// render in lazy construction, so we need to do the same here.
|
|||
|
|
transferStaticProps(_ProxyFacade, savedDescriptors, null, CurrentComponent);
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Otherwise, it's a normal functional component. Build the real proxy
|
|||
|
|
// and use it going forward.
|
|||
|
|
ProxyComponent = proxyClassCreator(React.Component, postConstructionAction);
|
|||
|
|
|
|||
|
|
defineProxyMethods(ProxyComponent);
|
|||
|
|
|
|||
|
|
var determinateResult = new ProxyComponent(props, context);
|
|||
|
|
|
|||
|
|
// Cache the initial render result so we don't call the component function
|
|||
|
|
// a second time for the initial render.
|
|||
|
|
determinateResult[CACHED_RESULT] = result;
|
|||
|
|
return determinateResult;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function get$$1() {
|
|||
|
|
return _ProxyFacade;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function getCurrent() {
|
|||
|
|
return CurrentComponent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
safeDefineProperty(_ProxyFacade, UNWRAP_PROXY, {
|
|||
|
|
configurable: false,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: getCurrent
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
safeDefineProperty(_ProxyFacade, PROXY_KEY, {
|
|||
|
|
configurable: false,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: proxyKey
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
safeDefineProperty(_ProxyFacade, 'toString', {
|
|||
|
|
configurable: true,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: function toString() {
|
|||
|
|
return String(CurrentComponent);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function update(NextComponent) {
|
|||
|
|
if (typeof NextComponent !== 'function') {
|
|||
|
|
throw new Error('Expected a constructor.');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (NextComponent === CurrentComponent) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Prevent proxy cycles
|
|||
|
|
var existingProxy = proxies.get(NextComponent);
|
|||
|
|
if (existingProxy) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
isFunctionalComponent = !isReactClass(NextComponent);
|
|||
|
|
|
|||
|
|
proxies.set(NextComponent, proxy);
|
|||
|
|
|
|||
|
|
proxyGeneration++;
|
|||
|
|
|
|||
|
|
// Save the next constructor so we call it
|
|||
|
|
var PreviousComponent = CurrentComponent;
|
|||
|
|
CurrentComponent = NextComponent;
|
|||
|
|
|
|||
|
|
// Try to infer displayName
|
|||
|
|
var displayName = getComponentDisplayName(CurrentComponent);
|
|||
|
|
|
|||
|
|
safeDefineProperty(_ProxyFacade, 'displayName', {
|
|||
|
|
configurable: true,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: true,
|
|||
|
|
value: displayName
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (ProxyComponent) {
|
|||
|
|
safeDefineProperty(ProxyComponent, 'name', {
|
|||
|
|
value: displayName
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
savedDescriptors = transferStaticProps(_ProxyFacade, savedDescriptors, PreviousComponent, NextComponent);
|
|||
|
|
|
|||
|
|
if (isFunctionalComponent || !ProxyComponent) ; else {
|
|||
|
|
var classHotReplacement = function classHotReplacement() {
|
|||
|
|
checkLifeCycleMethods(ProxyComponent, NextComponent);
|
|||
|
|
Object.setPrototypeOf(ProxyComponent.prototype, NextComponent.prototype);
|
|||
|
|
defineProxyMethods(ProxyComponent, NextComponent.prototype);
|
|||
|
|
if (proxyGeneration > 1) {
|
|||
|
|
injectedMembers = mergeComponents(ProxyComponent, NextComponent, InitialComponent, lastInstance, injectedMembers);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Was constructed once
|
|||
|
|
if (instancesCount > 0) {
|
|||
|
|
classHotReplacement();
|
|||
|
|
} else {
|
|||
|
|
classUpdatePostponed = classHotReplacement;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
update(InitialComponent);
|
|||
|
|
|
|||
|
|
var dereference = function dereference() {
|
|||
|
|
proxies.delete(InitialComponent);
|
|||
|
|
proxies.delete(_ProxyFacade);
|
|||
|
|
proxies.delete(CurrentComponent);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
proxy = { get: get$$1, update: update, dereference: dereference, getCurrent: function getCurrent() {
|
|||
|
|
return CurrentComponent;
|
|||
|
|
} };
|
|||
|
|
|
|||
|
|
proxies.set(InitialComponent, proxy);
|
|||
|
|
proxies.set(_ProxyFacade, proxy);
|
|||
|
|
|
|||
|
|
safeDefineProperty(proxy, UNWRAP_PROXY, {
|
|||
|
|
configurable: false,
|
|||
|
|
writable: false,
|
|||
|
|
enumerable: false,
|
|||
|
|
value: getCurrent
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return proxy;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var proxiesByID = void 0;
|
|||
|
|
var blackListedProxies = void 0;
|
|||
|
|
var registeredComponents = void 0;
|
|||
|
|
var idsByType = void 0;
|
|||
|
|
|
|||
|
|
var elementCount = 0;
|
|||
|
|
var renderOptions = {};
|
|||
|
|
|
|||
|
|
var generateTypeId = function generateTypeId() {
|
|||
|
|
return 'auto-' + elementCount++;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getIdByType = function getIdByType(type) {
|
|||
|
|
return idsByType.get(type);
|
|||
|
|
};
|
|||
|
|
var isProxyType = function isProxyType(type) {
|
|||
|
|
return type[PROXY_KEY];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getProxyById = function getProxyById(id) {
|
|||
|
|
return proxiesByID[id];
|
|||
|
|
};
|
|||
|
|
var getProxyByType = function getProxyByType(type) {
|
|||
|
|
return getProxyById(getIdByType(type));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var registerComponent = function registerComponent(type) {
|
|||
|
|
return registeredComponents.set(type, 1);
|
|||
|
|
};
|
|||
|
|
var isRegisteredComponent = function isRegisteredComponent(type) {
|
|||
|
|
return registeredComponents.has(type);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var setStandInOptions = function setStandInOptions(options) {
|
|||
|
|
renderOptions = options;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var updateProxyById = function updateProxyById(id, type) {
|
|||
|
|
// Remember the ID.
|
|||
|
|
idsByType.set(type, id);
|
|||
|
|
|
|||
|
|
if (!proxiesByID[id]) {
|
|||
|
|
proxiesByID[id] = createClassProxy(type, id, renderOptions);
|
|||
|
|
} else {
|
|||
|
|
proxiesByID[id].update(type);
|
|||
|
|
}
|
|||
|
|
return proxiesByID[id];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var createProxyForType = function createProxyForType(type) {
|
|||
|
|
return getProxyByType(type) || updateProxyById(generateTypeId(), type);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var isTypeBlacklisted = function isTypeBlacklisted(type) {
|
|||
|
|
return blackListedProxies.has(type);
|
|||
|
|
};
|
|||
|
|
var blacklistByType = function blacklistByType(type) {
|
|||
|
|
return blackListedProxies.set(type, true);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var resetProxies = function resetProxies() {
|
|||
|
|
proxiesByID = {};
|
|||
|
|
idsByType = new WeakMap();
|
|||
|
|
blackListedProxies = new WeakMap();
|
|||
|
|
registeredComponents = new WeakMap();
|
|||
|
|
resetClassProxies();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
resetProxies();
|
|||
|
|
|
|||
|
|
var tune = {
|
|||
|
|
allowSFC: false
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var preactAdapter = function preactAdapter(instance, resolveType) {
|
|||
|
|
var oldHandler = instance.options.vnode;
|
|||
|
|
|
|||
|
|
Object.assign(configuration, tune);
|
|||
|
|
|
|||
|
|
instance.options.vnode = function (vnode) {
|
|||
|
|
vnode.nodeName = resolveType(vnode.nodeName);
|
|||
|
|
if (oldHandler) {
|
|||
|
|
oldHandler(vnode);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-use-before-define */
|
|||
|
|
|
|||
|
|
function _resolveType(type) {
|
|||
|
|
if (!isCompositeComponent(type) || isTypeBlacklisted(type) || isProxyType(type)) return type;
|
|||
|
|
|
|||
|
|
var proxy = reactHotLoader.disableProxyCreation ? getProxyByType(type) : createProxyForType(type);
|
|||
|
|
|
|||
|
|
return proxy ? proxy.get() : type;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var reactHotLoader = {
|
|||
|
|
register: function register(type, uniqueLocalName, fileName) {
|
|||
|
|
if (isCompositeComponent(type) && typeof uniqueLocalName === 'string' && uniqueLocalName && typeof fileName === 'string' && fileName) {
|
|||
|
|
var id = fileName + '#' + uniqueLocalName;
|
|||
|
|
var proxy = getProxyById(id);
|
|||
|
|
|
|||
|
|
if (proxy && proxy.getCurrent() !== type) {
|
|||
|
|
// component got replaced. Need to reconcile
|
|||
|
|
increment();
|
|||
|
|
|
|||
|
|
if (isTypeBlacklisted(type) || isTypeBlacklisted(proxy.getCurrent())) {
|
|||
|
|
logger.error('React-hot-loader: Cold component', uniqueLocalName, 'at', fileName, 'has been updated');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (configuration.onComponentRegister) {
|
|||
|
|
configuration.onComponentRegister(type, uniqueLocalName, fileName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
updateProxyById(id, type);
|
|||
|
|
registerComponent(type);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
reset: function reset() {
|
|||
|
|
resetProxies();
|
|||
|
|
},
|
|||
|
|
preact: function preact(instance) {
|
|||
|
|
preactAdapter(instance, _resolveType);
|
|||
|
|
},
|
|||
|
|
resolveType: function resolveType(type) {
|
|||
|
|
return _resolveType(type);
|
|||
|
|
},
|
|||
|
|
patch: function patch(React$$1) {
|
|||
|
|
if (!React$$1.createElement.isPatchedByReactHotLoader) {
|
|||
|
|
var originalCreateElement = React$$1.createElement;
|
|||
|
|
// Trick React into rendering a proxy so that
|
|||
|
|
// its state is preserved when the class changes.
|
|||
|
|
// This will update the proxy if it's for a known type.
|
|||
|
|
React$$1.createElement = function (type) {
|
|||
|
|
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|||
|
|
args[_key - 1] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return originalCreateElement.apply(undefined, [_resolveType(type)].concat(args));
|
|||
|
|
};
|
|||
|
|
React$$1.createElement.isPatchedByReactHotLoader = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!React$$1.createFactory.isPatchedByReactHotLoader) {
|
|||
|
|
// Patch React.createFactory to use patched createElement
|
|||
|
|
// because the original implementation uses the internal,
|
|||
|
|
// unpatched ReactElement.createElement
|
|||
|
|
React$$1.createFactory = function (type) {
|
|||
|
|
var factory = React$$1.createElement.bind(null, type);
|
|||
|
|
factory.type = type;
|
|||
|
|
return factory;
|
|||
|
|
};
|
|||
|
|
React$$1.createFactory.isPatchedByReactHotLoader = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!React$$1.Children.only.isPatchedByReactHotLoader) {
|
|||
|
|
var originalChildrenOnly = React$$1.Children.only;
|
|||
|
|
// Use the same trick as React.createElement
|
|||
|
|
React$$1.Children.only = function (children) {
|
|||
|
|
return originalChildrenOnly(_extends({}, children, { type: _resolveType(children.type) }));
|
|||
|
|
};
|
|||
|
|
React$$1.Children.only.isPatchedByReactHotLoader = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
reactHotLoader.reset();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
|
|||
|
|
disableProxyCreation: false
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable no-underscore-dangle */
|
|||
|
|
|
|||
|
|
function pushStack(stack, node) {
|
|||
|
|
stack.type = node.type;
|
|||
|
|
stack.children = [];
|
|||
|
|
stack.instance = typeof node.type === 'function' ? node.stateNode : stack;
|
|||
|
|
|
|||
|
|
if (!stack.instance) {
|
|||
|
|
stack.instance = {
|
|||
|
|
SFC_fake: stack.type,
|
|||
|
|
props: {},
|
|||
|
|
render: function render() {
|
|||
|
|
return stack.type(stack.instance.props);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hydrateFiberStack(node, stack) {
|
|||
|
|
pushStack(stack, node);
|
|||
|
|
if (node.child) {
|
|||
|
|
var child = node.child;
|
|||
|
|
|
|||
|
|
do {
|
|||
|
|
var childStack = {};
|
|||
|
|
hydrateFiberStack(child, childStack);
|
|||
|
|
stack.children.push(childStack);
|
|||
|
|
child = child.sibling;
|
|||
|
|
} while (child);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* eslint-disable no-underscore-dangle */
|
|||
|
|
|
|||
|
|
function pushState(stack, type, instance) {
|
|||
|
|
stack.type = type;
|
|||
|
|
stack.children = [];
|
|||
|
|
stack.instance = instance || stack;
|
|||
|
|
|
|||
|
|
if (typeof type === 'function' && type.isStatelessFunctionalProxy) {
|
|||
|
|
// In React 15 SFC is wrapped by component. We have to detect our proxies and change the way it works
|
|||
|
|
stack.instance = {
|
|||
|
|
SFC_fake: type,
|
|||
|
|
props: {},
|
|||
|
|
render: function render() {
|
|||
|
|
return type(stack.instance.props);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hydrateLegacyStack(node, stack) {
|
|||
|
|
if (node._currentElement) {
|
|||
|
|
pushState(stack, node._currentElement.type, node._instance || stack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (node._renderedComponent) {
|
|||
|
|
var childStack = {};
|
|||
|
|
hydrateLegacyStack(node._renderedComponent, childStack);
|
|||
|
|
stack.children.push(childStack);
|
|||
|
|
} else if (node._renderedChildren) {
|
|||
|
|
Object.keys(node._renderedChildren).forEach(function (key) {
|
|||
|
|
var childStack = {};
|
|||
|
|
hydrateLegacyStack(node._renderedChildren[key], childStack);
|
|||
|
|
stack.children.push(childStack);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* eslint-disable no-underscore-dangle */
|
|||
|
|
|
|||
|
|
function getReactStack(instance) {
|
|||
|
|
var rootNode = getInternalInstance(instance);
|
|||
|
|
var stack = {};
|
|||
|
|
if (rootNode) {
|
|||
|
|
// React stack
|
|||
|
|
var isFiber = typeof rootNode.tag === 'number';
|
|||
|
|
if (isFiber) {
|
|||
|
|
hydrateFiberStack(rootNode, stack);
|
|||
|
|
} else {
|
|||
|
|
hydrateLegacyStack(rootNode, stack);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return stack;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// some `empty` names, React can autoset display name to...
|
|||
|
|
var UNDEFINED_NAMES = {
|
|||
|
|
Unknown: true,
|
|||
|
|
Component: true
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var renderStack = [];
|
|||
|
|
|
|||
|
|
var stackReport = function stackReport() {
|
|||
|
|
var rev = renderStack.slice().reverse();
|
|||
|
|
logger.warn('in', rev[0].name, rev);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var emptyMap = new Map();
|
|||
|
|
var stackContext = function stackContext() {
|
|||
|
|
return (renderStack[renderStack.length - 1] || {}).context || emptyMap;
|
|||
|
|
};
|
|||
|
|
var areNamesEqual = function areNamesEqual(a, b) {
|
|||
|
|
return a === b || UNDEFINED_NAMES[a] && UNDEFINED_NAMES[b];
|
|||
|
|
};
|
|||
|
|
var shouldUseRenderMethod = function shouldUseRenderMethod(fn) {
|
|||
|
|
return fn && (isReactClassInstance(fn) || fn.SFC_fake);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var isFunctional = function isFunctional(fn) {
|
|||
|
|
return typeof fn === 'function';
|
|||
|
|
};
|
|||
|
|
var isArray = function isArray(fn) {
|
|||
|
|
return Array.isArray(fn);
|
|||
|
|
};
|
|||
|
|
var asArray = function asArray(a) {
|
|||
|
|
return isArray(a) ? a : [a];
|
|||
|
|
};
|
|||
|
|
var getTypeOf = function getTypeOf(type) {
|
|||
|
|
if (isReactClass(type)) return 'ReactComponent';
|
|||
|
|
if (isFunctional(type)) return 'StatelessFunctional';
|
|||
|
|
return 'Fragment'; // ?
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var filterNullArray = function filterNullArray(a) {
|
|||
|
|
if (!a) return [];
|
|||
|
|
return a.filter(function (x) {
|
|||
|
|
return !!x;
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var unflatten = function unflatten(a) {
|
|||
|
|
return a.reduce(function (acc, a) {
|
|||
|
|
if (Array.isArray(a)) {
|
|||
|
|
acc.push.apply(acc, unflatten(a));
|
|||
|
|
} else {
|
|||
|
|
acc.push(a);
|
|||
|
|
}
|
|||
|
|
return acc;
|
|||
|
|
}, []);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getElementType = function getElementType(child) {
|
|||
|
|
return child.type[UNWRAP_PROXY] ? child.type[UNWRAP_PROXY]() : child.type;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var haveTextSimilarity = function haveTextSimilarity(a, b) {
|
|||
|
|
return (
|
|||
|
|
// equal or slight changed
|
|||
|
|
a === b || levenshtein.get(a, b) < a.length * 0.2
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var equalClasses = function equalClasses(a, b) {
|
|||
|
|
var prototypeA = a.prototype;
|
|||
|
|
var prototypeB = Object.getPrototypeOf(b.prototype);
|
|||
|
|
|
|||
|
|
var hits = 0;
|
|||
|
|
var misses = 0;
|
|||
|
|
var comparisons = 0;
|
|||
|
|
Object.getOwnPropertyNames(prototypeA).forEach(function (key) {
|
|||
|
|
var descriptorA = Object.getOwnPropertyDescriptor(prototypeA, key);
|
|||
|
|
var valueA = descriptorA && (descriptorA.value || descriptorA.get || descriptorA.set);
|
|||
|
|
var descriptorB = Object.getOwnPropertyDescriptor(prototypeB, key);
|
|||
|
|
var valueB = descriptorB && (descriptorB.value || descriptorB.get || descriptorB.set);
|
|||
|
|
|
|||
|
|
if (typeof valueA === 'function' && key !== 'constructor') {
|
|||
|
|
comparisons++;
|
|||
|
|
if (haveTextSimilarity(String(valueA), String(valueB))) {
|
|||
|
|
hits++;
|
|||
|
|
} else {
|
|||
|
|
misses++;
|
|||
|
|
if (key === 'render') {
|
|||
|
|
misses++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
// allow to add or remove one function
|
|||
|
|
return hits > 0 && misses <= 1 || comparisons === 0;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var areSwappable = function areSwappable(a, b) {
|
|||
|
|
// both are registered components and have the same name
|
|||
|
|
if (getIdByType(b) && getIdByType(a) === getIdByType(b)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
if (getTypeOf(a) !== getTypeOf(b)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (isReactClass(a)) {
|
|||
|
|
return areNamesEqual(getComponentDisplayName(a), getComponentDisplayName(b)) && equalClasses(a, b);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isFunctional(a)) {
|
|||
|
|
var nameA = getComponentDisplayName(a);
|
|||
|
|
return areNamesEqual(nameA, getComponentDisplayName(b)) && nameA !== 'Component' || haveTextSimilarity(String(a), String(b));
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var render = function render(component) {
|
|||
|
|
if (!component) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
if (shouldUseRenderMethod(component)) {
|
|||
|
|
// not calling real render method to prevent call recursion.
|
|||
|
|
// stateless components does not have hotComponentRender
|
|||
|
|
return component.hotComponentRender ? component.hotComponentRender() : component.render();
|
|||
|
|
}
|
|||
|
|
if (isArray(component)) {
|
|||
|
|
return component.map(render);
|
|||
|
|
}
|
|||
|
|
if (component.children) {
|
|||
|
|
return component.children;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return [];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var NO_CHILDREN = { children: [] };
|
|||
|
|
var mapChildren = function mapChildren(children, instances) {
|
|||
|
|
return {
|
|||
|
|
children: children.filter(function (c) {
|
|||
|
|
return c;
|
|||
|
|
}).map(function (child, index) {
|
|||
|
|
if ((typeof child === 'undefined' ? 'undefined' : _typeof(child)) !== 'object' || child.isMerged) {
|
|||
|
|
return child;
|
|||
|
|
}
|
|||
|
|
var instanceLine = instances[index] || {};
|
|||
|
|
var oldChildren = asArray(instanceLine.children || []);
|
|||
|
|
|
|||
|
|
if (Array.isArray(child)) {
|
|||
|
|
return _extends({
|
|||
|
|
type: null
|
|||
|
|
}, mapChildren(child, oldChildren));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var newChildren = asArray(child.props && child.props.children || child.children || []);
|
|||
|
|
var nextChildren = child.type !== 'function' && oldChildren.length && mapChildren(newChildren, oldChildren);
|
|||
|
|
|
|||
|
|
return _extends({
|
|||
|
|
nextProps: child.props,
|
|||
|
|
isMerged: true
|
|||
|
|
}, instanceLine, nextChildren || {}, {
|
|||
|
|
type: child.type
|
|||
|
|
});
|
|||
|
|
})
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var mergeInject = function mergeInject(a, b, instance) {
|
|||
|
|
if (a && !Array.isArray(a)) {
|
|||
|
|
return mergeInject([a], b);
|
|||
|
|
}
|
|||
|
|
if (b && !Array.isArray(b)) {
|
|||
|
|
return mergeInject(a, [b]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!a || !b) {
|
|||
|
|
return NO_CHILDREN;
|
|||
|
|
}
|
|||
|
|
if (a.length === b.length) {
|
|||
|
|
return mapChildren(a, b);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// in some cases (no confidence here) B could contain A except null children
|
|||
|
|
// in some cases - could not.
|
|||
|
|
// this depends on React version and the way you build component.
|
|||
|
|
|
|||
|
|
var nonNullA = filterNullArray(a);
|
|||
|
|
if (nonNullA.length === b.length) {
|
|||
|
|
return mapChildren(nonNullA, b);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var flatA = unflatten(nonNullA);
|
|||
|
|
var flatB = unflatten(b);
|
|||
|
|
if (flatA.length === flatB.length) {
|
|||
|
|
return mapChildren(flatA, flatB);
|
|||
|
|
}
|
|||
|
|
if (flatB.length === 0 && flatA.length === 1 && _typeof(flatA[0]) !== 'object') ; else {
|
|||
|
|
logger.warn('React-hot-loader: unable to merge ', a, 'and children of ', instance);
|
|||
|
|
stackReport();
|
|||
|
|
}
|
|||
|
|
return NO_CHILDREN;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var transformFlowNode = function transformFlowNode(flow) {
|
|||
|
|
return flow.reduce(function (acc, node) {
|
|||
|
|
if (node && isFragmentNode(node)) {
|
|||
|
|
if (node.props && node.props.children) {
|
|||
|
|
return [].concat(acc, filterNullArray(asArray(node.props.children)));
|
|||
|
|
}
|
|||
|
|
if (node.children) {
|
|||
|
|
return [].concat(acc, filterNullArray(asArray(node.children)));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return [].concat(acc, [node]);
|
|||
|
|
}, []);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var scheduledUpdates = [];
|
|||
|
|
var scheduledUpdate = 0;
|
|||
|
|
|
|||
|
|
var flushScheduledUpdates = function flushScheduledUpdates() {
|
|||
|
|
var instances = scheduledUpdates;
|
|||
|
|
scheduledUpdates = [];
|
|||
|
|
scheduledUpdate = 0;
|
|||
|
|
instances.forEach(function (instance) {
|
|||
|
|
return instance[PROXY_IS_MOUNTED] && updateInstance(instance);
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var unscheduleUpdate = function unscheduleUpdate(instance) {
|
|||
|
|
scheduledUpdates = scheduledUpdates.filter(function (inst) {
|
|||
|
|
return inst !== instance;
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var scheduleInstanceUpdate = function scheduleInstanceUpdate(instance) {
|
|||
|
|
scheduledUpdates.push(instance);
|
|||
|
|
if (!scheduledUpdate) {
|
|||
|
|
scheduledUpdate = setTimeout(flushScheduledUpdates);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hotReplacementRender = function hotReplacementRender(instance, stack) {
|
|||
|
|
if (isReactClassInstance(instance)) {
|
|||
|
|
var type = getElementType(stack);
|
|||
|
|
|
|||
|
|
renderStack.push({
|
|||
|
|
name: getComponentDisplayName(type),
|
|||
|
|
type: type,
|
|||
|
|
props: stack.instance.props,
|
|||
|
|
context: stackContext()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
var flow = transformFlowNode(filterNullArray(asArray(render(instance))));
|
|||
|
|
|
|||
|
|
var children = stack.children;
|
|||
|
|
|
|||
|
|
|
|||
|
|
flow.forEach(function (child, index) {
|
|||
|
|
var stackChild = children[index];
|
|||
|
|
var next = function next(instance) {
|
|||
|
|
// copy over props as long new component may be hidden inside them
|
|||
|
|
// child does not have all props, as long some of them can be calculated on componentMount.
|
|||
|
|
var realProps = instance.props;
|
|||
|
|
var nextProps = _extends({}, realProps, child.nextProps || {}, child.props || {});
|
|||
|
|
|
|||
|
|
if (isReactClassInstance(instance) && instance.componentWillUpdate) {
|
|||
|
|
// Force-refresh component (bypass redux renderedComponent)
|
|||
|
|
instance.componentWillUpdate(_extends({}, realProps), instance.state);
|
|||
|
|
}
|
|||
|
|
instance.props = nextProps;
|
|||
|
|
hotReplacementRender(instance, stackChild);
|
|||
|
|
instance.props = realProps;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// text node
|
|||
|
|
if ((typeof child === 'undefined' ? 'undefined' : _typeof(child)) !== 'object' || !stackChild || !stackChild.instance) {
|
|||
|
|
if (stackChild && stackChild.children && stackChild.children.length) {
|
|||
|
|
logger.error('React-hot-loader: reconciliation failed', 'could not dive into [', child, '] while some elements are still present in the tree.');
|
|||
|
|
stackReport();
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_typeof(child.type) !== _typeof(stackChild.type)) {
|
|||
|
|
// Portals could generate undefined !== null
|
|||
|
|
if (child.type && stackChild.type) {
|
|||
|
|
logger.warn('React-hot-loader: got ', child.type, 'instead of', stackChild.type);
|
|||
|
|
stackReport();
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// React context
|
|||
|
|
if (isContextConsumer(child)) {
|
|||
|
|
try {
|
|||
|
|
next({
|
|||
|
|
children: (child.props ? child.props.children : child.children[0])(stackContext().get(child.type) || child.type[CONTEXT_CURRENT_VALUE])
|
|||
|
|
});
|
|||
|
|
} catch (e) {
|
|||
|
|
// do nothing, yet
|
|||
|
|
}
|
|||
|
|
} else if (typeof child.type !== 'function') {
|
|||
|
|
// React
|
|||
|
|
var childName = child.type ? getComponentDisplayName(child.type) : 'empty';
|
|||
|
|
var extraContext = stackContext();
|
|||
|
|
|
|||
|
|
if (isContextProvider(child)) {
|
|||
|
|
extraContext = new Map(extraContext);
|
|||
|
|
extraContext.set(getContextProvider(child.type), _extends({}, child.nextProps || {}, child.props || {}).value);
|
|||
|
|
childName = 'ContextProvider';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
renderStack.push({
|
|||
|
|
name: childName,
|
|||
|
|
type: child.type,
|
|||
|
|
props: stack.instance.props,
|
|||
|
|
context: extraContext
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
next(
|
|||
|
|
// move types from render to the instances of hydrated tree
|
|||
|
|
mergeInject(transformFlowNode(asArray(child.props ? child.props.children : child.children)), stackChild.instance.children, stackChild.instance));
|
|||
|
|
renderStack.pop();
|
|||
|
|
} else {
|
|||
|
|
if (child.type === stackChild.type) {
|
|||
|
|
next(stackChild.instance);
|
|||
|
|
} else {
|
|||
|
|
// unwrap proxy
|
|||
|
|
var childType = getElementType(child);
|
|||
|
|
if (!stackChild.type[PROXY_KEY]) {
|
|||
|
|
if (isTypeBlacklisted(stackChild.type)) {
|
|||
|
|
logger.warn('React-hot-loader: cold element got updated ', stackChild.type);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
/* eslint-disable no-console */
|
|||
|
|
logger.error('React-hot-loader: fatal error caused by ', stackChild.type, ' - no instrumentation found. ', 'Please require react-hot-loader before React. More in troubleshooting.');
|
|||
|
|
stackReport();
|
|||
|
|
throw new Error('React-hot-loader: wrong configuration');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (isRegisteredComponent(childType) || isRegisteredComponent(stackChild.type)) ; else if (areSwappable(childType, stackChild.type)) {
|
|||
|
|
// they are both registered, or have equal code/displayname/signature
|
|||
|
|
|
|||
|
|
// update proxy using internal PROXY_KEY
|
|||
|
|
updateProxyById(stackChild.type[PROXY_KEY], childType);
|
|||
|
|
|
|||
|
|
next(stackChild.instance);
|
|||
|
|
} else {
|
|||
|
|
logger.warn('React-hot-loader: a ' + getComponentDisplayName(childType) + ' was found where a ' + getComponentDisplayName(stackChild) + ' was expected.\n ' + childType);
|
|||
|
|
stackReport();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
scheduleInstanceUpdate(stackChild.instance);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (isReactClassInstance(instance)) {
|
|||
|
|
renderStack.pop();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hotComponentCompare = function hotComponentCompare(oldType, newType) {
|
|||
|
|
if (oldType === newType) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (areSwappable(newType, oldType)) {
|
|||
|
|
getProxyByType(newType[UNWRAP_PROXY]()).dereference();
|
|||
|
|
updateProxyById(oldType[PROXY_KEY], newType[UNWRAP_PROXY]());
|
|||
|
|
updateProxyById(newType[PROXY_KEY], oldType[UNWRAP_PROXY]());
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hotReplacementRender$1 = (function (instance, stack) {
|
|||
|
|
try {
|
|||
|
|
// disable reconciler to prevent upcoming components from proxying.
|
|||
|
|
reactHotLoader.disableProxyCreation = true;
|
|||
|
|
renderStack = [];
|
|||
|
|
hotReplacementRender(instance, stack);
|
|||
|
|
} catch (e) {
|
|||
|
|
logger.warn('React-hot-loader: reconcilation failed due to error', e);
|
|||
|
|
} finally {
|
|||
|
|
reactHotLoader.disableProxyCreation = false;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var reconcileHotReplacement = function reconcileHotReplacement(ReactInstance) {
|
|||
|
|
return hotReplacementRender$1(ReactInstance, getReactStack(ReactInstance));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var RENDERED_GENERATION = 'REACT_HOT_LOADER_RENDERED_GENERATION';
|
|||
|
|
|
|||
|
|
var renderReconciler = function renderReconciler(target, force) {
|
|||
|
|
// we are not inside parent reconcilation
|
|||
|
|
var currentGeneration = get$1();
|
|||
|
|
var componentGeneration = target[RENDERED_GENERATION];
|
|||
|
|
|
|||
|
|
target[RENDERED_GENERATION] = currentGeneration;
|
|||
|
|
|
|||
|
|
if (!reactHotLoader.disableProxyCreation) {
|
|||
|
|
if ((componentGeneration || force) && componentGeneration !== currentGeneration) {
|
|||
|
|
reconcileHotReplacement(target);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function asyncReconciledRender(target) {
|
|||
|
|
renderReconciler(target, false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function proxyWrapper(element) {
|
|||
|
|
// post wrap on post render
|
|||
|
|
if (!reactHotLoader.disableProxyCreation) {
|
|||
|
|
unscheduleUpdate(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!element) {
|
|||
|
|
return element;
|
|||
|
|
}
|
|||
|
|
if (Array.isArray(element)) {
|
|||
|
|
return element.map(proxyWrapper);
|
|||
|
|
}
|
|||
|
|
if (typeof element.type === 'function') {
|
|||
|
|
var proxy = getProxyByType(element.type);
|
|||
|
|
if (proxy) {
|
|||
|
|
return _extends({}, element, {
|
|||
|
|
type: proxy.get()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return element;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setStandInOptions({
|
|||
|
|
componentWillRender: asyncReconciledRender,
|
|||
|
|
componentDidRender: proxyWrapper,
|
|||
|
|
componentDidUpdate: flushScheduledUpdates
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
var AppContainer = function (_React$Component) {
|
|||
|
|
inherits(AppContainer, _React$Component);
|
|||
|
|
|
|||
|
|
function AppContainer() {
|
|||
|
|
var _temp, _this, _ret;
|
|||
|
|
|
|||
|
|
classCallCheck(this, AppContainer);
|
|||
|
|
|
|||
|
|
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|||
|
|
args[_key] = arguments[_key];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return _ret = (_temp = (_this = possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
|
|||
|
|
error: null,
|
|||
|
|
// eslint-disable-next-line react/no-unused-state
|
|||
|
|
generation: 0
|
|||
|
|
}, _temp), possibleConstructorReturn(_this, _ret);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AppContainer.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
|
|||
|
|
if (prevState.generation !== get$1()) {
|
|||
|
|
// Hot reload is happening.
|
|||
|
|
return {
|
|||
|
|
error: null,
|
|||
|
|
generation: get$1()
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
AppContainer.prototype.shouldComponentUpdate = function shouldComponentUpdate(prevProps, prevState) {
|
|||
|
|
// Don't update the component if the state had an error and still has one.
|
|||
|
|
// This allows to break an infinite loop of error -> render -> error -> render
|
|||
|
|
// https://github.com/gaearon/react-hot-loader/issues/696
|
|||
|
|
if (prevState.error && this.state.error) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
AppContainer.prototype.componentDidCatch = function componentDidCatch(error) {
|
|||
|
|
logger.error(error);
|
|||
|
|
this.setState({ error: error });
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
AppContainer.prototype.render = function render() {
|
|||
|
|
var error = this.state.error;
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (this.props.errorReporter && error) {
|
|||
|
|
return React__default.createElement(this.props.errorReporter, { error: error });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return React__default.Children.only(this.props.children);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return AppContainer;
|
|||
|
|
}(React__default.Component);
|
|||
|
|
|
|||
|
|
AppContainer.propTypes = {
|
|||
|
|
children: function children(props) {
|
|||
|
|
if (React__default.Children.count(props.children) !== 1) {
|
|||
|
|
return new Error('Invalid prop "children" supplied to AppContainer. ' + 'Expected a single React element with your app’s root component, e.g. <App />.');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return undefined;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
errorReporter: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
|
|||
|
|
|
|||
|
|
// trying first react-lifecycles-compat.polyfill, then trying react-lifecycles-compat, which could be .default
|
|||
|
|
};var realPolyfill = defaultPolyfill.polyfill || defaultPolyfill__default;
|
|||
|
|
realPolyfill(AppContainer);
|
|||
|
|
|
|||
|
|
var openedModules = {};
|
|||
|
|
|
|||
|
|
var hotModules = {};
|
|||
|
|
|
|||
|
|
var createHotModule = function createHotModule() {
|
|||
|
|
return { instances: [], updateTimeout: 0 };
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hotModule = function hotModule(moduleId) {
|
|||
|
|
if (!hotModules[moduleId]) {
|
|||
|
|
hotModules[moduleId] = createHotModule();
|
|||
|
|
}
|
|||
|
|
return hotModules[moduleId];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var isOpened = function isOpened(sourceModule) {
|
|||
|
|
return sourceModule && !!openedModules[sourceModule.id];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var enter = function enter(sourceModule) {
|
|||
|
|
if (sourceModule && sourceModule.id) {
|
|||
|
|
openedModules[sourceModule.id] = true;
|
|||
|
|
} else {
|
|||
|
|
logger.warn('React-hot-loader: no `module` variable found. Do you shadow system variable?');
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var leave = function leave(sourceModule) {
|
|||
|
|
if (sourceModule && sourceModule.id) {
|
|||
|
|
delete openedModules[sourceModule.id];
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/* eslint-disable camelcase, no-undef */
|
|||
|
|
var requireIndirect = typeof __webpack_require__ !== 'undefined' ? __webpack_require__ : require;
|
|||
|
|
/* eslint-enable */
|
|||
|
|
|
|||
|
|
var createHoc = function createHoc(SourceComponent, TargetComponent) {
|
|||
|
|
hoistNonReactStatic(TargetComponent, SourceComponent);
|
|||
|
|
TargetComponent.displayName = 'HotExported' + getComponentDisplayName(SourceComponent);
|
|||
|
|
return TargetComponent;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var makeHotExport = function makeHotExport(sourceModule) {
|
|||
|
|
var updateInstances = function updateInstances() {
|
|||
|
|
var module = hotModule(sourceModule.id);
|
|||
|
|
clearTimeout(module.updateTimeout);
|
|||
|
|
module.updateTimeout = setTimeout(function () {
|
|||
|
|
try {
|
|||
|
|
requireIndirect(sourceModule.id);
|
|||
|
|
} catch (e) {
|
|||
|
|
// just swallow
|
|||
|
|
}
|
|||
|
|
module.instances.forEach(function (inst) {
|
|||
|
|
return inst.forceUpdate();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (sourceModule.hot) {
|
|||
|
|
// Mark as self-accepted for Webpack
|
|||
|
|
// Update instances for Parcel
|
|||
|
|
sourceModule.hot.accept(updateInstances);
|
|||
|
|
|
|||
|
|
// Webpack way
|
|||
|
|
if (sourceModule.hot.addStatusHandler) {
|
|||
|
|
if (sourceModule.hot.status() === 'idle') {
|
|||
|
|
sourceModule.hot.addStatusHandler(function (status) {
|
|||
|
|
if (status === 'apply') {
|
|||
|
|
updateInstances();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var hot = function hot(sourceModule) {
|
|||
|
|
if (!sourceModule || !sourceModule.id) {
|
|||
|
|
// this is fatal
|
|||
|
|
throw new Error('React-hot-loader: `hot` could not find the `id` property in the `module` you have provided');
|
|||
|
|
}
|
|||
|
|
var moduleId = sourceModule.id;
|
|||
|
|
var module = hotModule(moduleId);
|
|||
|
|
makeHotExport(sourceModule);
|
|||
|
|
|
|||
|
|
// TODO: Ensure that all exports from this file are react components.
|
|||
|
|
|
|||
|
|
return function (WrappedComponent) {
|
|||
|
|
// register proxy for wrapped component
|
|||
|
|
reactHotLoader.register(WrappedComponent, getComponentDisplayName(WrappedComponent), 'RHL' + moduleId);
|
|||
|
|
|
|||
|
|
return createHoc(WrappedComponent, function (_Component) {
|
|||
|
|
inherits(ExportedComponent, _Component);
|
|||
|
|
|
|||
|
|
function ExportedComponent() {
|
|||
|
|
classCallCheck(this, ExportedComponent);
|
|||
|
|
return possibleConstructorReturn(this, _Component.apply(this, arguments));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ExportedComponent.prototype.componentDidMount = function componentDidMount() {
|
|||
|
|
module.instances.push(this);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
ExportedComponent.prototype.componentWillUnmount = function componentWillUnmount() {
|
|||
|
|
var _this2 = this;
|
|||
|
|
|
|||
|
|
if (isOpened(sourceModule)) {
|
|||
|
|
var componentName = getComponentDisplayName(WrappedComponent);
|
|||
|
|
logger.error('React-hot-loader: Detected AppContainer unmount on module \'' + moduleId + '\' update.\n' + ('Did you use "hot(' + componentName + ')" and "ReactDOM.render()" in the same file?\n') + ('"hot(' + componentName + ')" shall only be used as export.\n') + 'Please refer to "Getting Started" (https://github.com/gaearon/react-hot-loader/).');
|
|||
|
|
}
|
|||
|
|
module.instances = module.instances.filter(function (a) {
|
|||
|
|
return a !== _this2;
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
ExportedComponent.prototype.render = function render() {
|
|||
|
|
return React__default.createElement(
|
|||
|
|
AppContainer,
|
|||
|
|
null,
|
|||
|
|
React__default.createElement(WrappedComponent, this.props)
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return ExportedComponent;
|
|||
|
|
}(React.Component));
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var getProxyOrType = function getProxyOrType(type) {
|
|||
|
|
var proxy = getProxyByType(type);
|
|||
|
|
return proxy ? proxy.get() : type;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var areComponentsEqual = function areComponentsEqual(a, b) {
|
|||
|
|
return getProxyOrType(a) === getProxyOrType(b);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var compareOrSwap = function compareOrSwap(oldType, newType) {
|
|||
|
|
return hotComponentCompare(oldType, newType);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var cold = function cold(type) {
|
|||
|
|
blacklistByType(type);
|
|||
|
|
return type;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var setConfig = function setConfig(config) {
|
|||
|
|
return Object.assign(configuration, config);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
reactHotLoader.patch(React__default);
|
|||
|
|
|
|||
|
|
exports.default = reactHotLoader;
|
|||
|
|
exports.AppContainer = AppContainer;
|
|||
|
|
exports.hot = hot;
|
|||
|
|
exports.enterModule = enter;
|
|||
|
|
exports.leaveModule = leave;
|
|||
|
|
exports.areComponentsEqual = areComponentsEqual;
|
|||
|
|
exports.compareOrSwap = compareOrSwap;
|
|||
|
|
exports.cold = cold;
|
|||
|
|
exports.setConfig = setConfig;
|