506 lines
16 KiB
JavaScript
506 lines
16 KiB
JavaScript
/** @license React v0.20.4
|
|
* react-reconciler-reflection.development.js
|
|
*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
(function() {
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var React = require('react');
|
|
|
|
/**
|
|
* Use invariant() to assert state which your program assumes to be true.
|
|
*
|
|
* Provide sprintf-style format (only %s is supported) and arguments
|
|
* to provide information about what broke and what you were
|
|
* expecting.
|
|
*
|
|
* The invariant message will be stripped in production, but the invariant
|
|
* will remain to ensure logic does not differ in production.
|
|
*/
|
|
|
|
var validateFormat = function () {};
|
|
|
|
{
|
|
validateFormat = function (format) {
|
|
if (format === undefined) {
|
|
throw new Error('invariant requires an error message argument');
|
|
}
|
|
};
|
|
}
|
|
|
|
function invariant(condition, format, a, b, c, d, e, f) {
|
|
validateFormat(format);
|
|
|
|
if (!condition) {
|
|
var error = void 0;
|
|
if (format === undefined) {
|
|
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
|
|
} else {
|
|
var args = [a, b, c, d, e, f];
|
|
var argIndex = 0;
|
|
error = new Error(format.replace(/%s/g, function () {
|
|
return args[argIndex++];
|
|
}));
|
|
error.name = 'Invariant Violation';
|
|
}
|
|
|
|
error.framesToPop = 1; // we don't care about invariant's own frame
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Relying on the `invariant()` implementation lets us
|
|
// preserve the format and params in the www builds.
|
|
|
|
/**
|
|
* Similar to invariant but only logs a warning if the condition is not met.
|
|
* This can be used to log issues in development environments in critical
|
|
* paths. Removing the logging code for production environments will keep the
|
|
* same logic and follow the same code paths.
|
|
*/
|
|
|
|
var warningWithoutStack = function () {};
|
|
|
|
{
|
|
warningWithoutStack = function (condition, format) {
|
|
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
args[_key - 2] = arguments[_key];
|
|
}
|
|
|
|
if (format === undefined) {
|
|
throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
|
|
}
|
|
if (args.length > 8) {
|
|
// Check before the condition to catch violations early.
|
|
throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
|
|
}
|
|
if (condition) {
|
|
return;
|
|
}
|
|
if (typeof console !== 'undefined') {
|
|
var argsWithFormat = args.map(function (item) {
|
|
return '' + item;
|
|
});
|
|
argsWithFormat.unshift('Warning: ' + format);
|
|
|
|
// We intentionally don't use spread (or .apply) directly because it
|
|
// breaks IE9: https://github.com/facebook/react/issues/13610
|
|
Function.prototype.apply.call(console.error, console, argsWithFormat);
|
|
}
|
|
try {
|
|
// --- Welcome to debugging React ---
|
|
// This error was thrown as a convenience so that you can use this stack
|
|
// to find the callsite that caused this warning to fire.
|
|
var argIndex = 0;
|
|
var message = 'Warning: ' + format.replace(/%s/g, function () {
|
|
return args[argIndex++];
|
|
});
|
|
throw new Error(message);
|
|
} catch (x) {}
|
|
};
|
|
}
|
|
|
|
var warningWithoutStack$1 = warningWithoutStack;
|
|
|
|
/**
|
|
* `ReactInstanceMap` maintains a mapping from a public facing stateful
|
|
* instance (key) and the internal representation (value). This allows public
|
|
* methods to accept the user facing instance as an argument and map them back
|
|
* to internal methods.
|
|
*
|
|
* Note that this module is currently shared and assumed to be stateless.
|
|
* If this becomes an actual Map, that will break.
|
|
*/
|
|
|
|
/**
|
|
* This API should be called `delete` but we'd have to make sure to always
|
|
* transform these to strings for IE support. When this transform is fully
|
|
* supported we can rename it.
|
|
*/
|
|
|
|
|
|
function get(key) {
|
|
return key._reactInternalFiber;
|
|
}
|
|
|
|
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
|
|
// Prevent newer renderers from RTE when used with older react package versions.
|
|
// Current owner and dispatcher used to share the same ref,
|
|
// but PR #14548 split them out to better support the react-debug-tools package.
|
|
if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
|
|
ReactSharedInternals.ReactCurrentDispatcher = {
|
|
current: null
|
|
};
|
|
}
|
|
|
|
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
|
// nor polyfill, then a plain number is used for performance.
|
|
var hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
|
|
|
|
|
var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
|
|
var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
|
|
var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
|
|
var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
|
|
var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
|
|
var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
|
|
|
|
var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
|
|
var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
|
|
var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
|
|
var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
|
|
var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
|
|
|
|
var Resolved = 1;
|
|
|
|
|
|
function refineResolvedLazyComponent(lazyComponent) {
|
|
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
|
}
|
|
|
|
function getWrappedName(outerType, innerType, wrapperName) {
|
|
var functionName = innerType.displayName || innerType.name || '';
|
|
return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
|
|
}
|
|
|
|
function getComponentName(type) {
|
|
if (type == null) {
|
|
// Host root, text node or just invalid type.
|
|
return null;
|
|
}
|
|
{
|
|
if (typeof type.tag === 'number') {
|
|
warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
|
}
|
|
}
|
|
if (typeof type === 'function') {
|
|
return type.displayName || type.name || null;
|
|
}
|
|
if (typeof type === 'string') {
|
|
return type;
|
|
}
|
|
switch (type) {
|
|
case REACT_CONCURRENT_MODE_TYPE:
|
|
return 'ConcurrentMode';
|
|
case REACT_FRAGMENT_TYPE:
|
|
return 'Fragment';
|
|
case REACT_PORTAL_TYPE:
|
|
return 'Portal';
|
|
case REACT_PROFILER_TYPE:
|
|
return 'Profiler';
|
|
case REACT_STRICT_MODE_TYPE:
|
|
return 'StrictMode';
|
|
case REACT_SUSPENSE_TYPE:
|
|
return 'Suspense';
|
|
}
|
|
if (typeof type === 'object') {
|
|
switch (type.$$typeof) {
|
|
case REACT_CONTEXT_TYPE:
|
|
return 'Context.Consumer';
|
|
case REACT_PROVIDER_TYPE:
|
|
return 'Context.Provider';
|
|
case REACT_FORWARD_REF_TYPE:
|
|
return getWrappedName(type, type.render, 'ForwardRef');
|
|
case REACT_MEMO_TYPE:
|
|
return getComponentName(type.type);
|
|
case REACT_LAZY_TYPE:
|
|
{
|
|
var thenable = type;
|
|
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
|
if (resolvedThenable) {
|
|
return getComponentName(resolvedThenable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
var ClassComponent = 1;
|
|
// Before we know whether it is function or class
|
|
var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
|
|
var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
|
|
var HostComponent = 5;
|
|
var HostText = 6;
|
|
|
|
// Don't change these two values. They're used by React Dev Tools.
|
|
var NoEffect = /* */0;
|
|
|
|
|
|
// You can change the rest (and add more).
|
|
var Placement = /* */2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Passive & Update & Callback & Ref & Snapshot
|
|
|
|
|
|
// Union of all host effects
|
|
|
|
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
|
|
|
var MOUNTING = 1;
|
|
var MOUNTED = 2;
|
|
var UNMOUNTED = 3;
|
|
|
|
function isFiberMountedImpl(fiber) {
|
|
var node = fiber;
|
|
if (!fiber.alternate) {
|
|
// If there is no alternate, this might be a new tree that isn't inserted
|
|
// yet. If it is, then it will have a pending insertion effect on it.
|
|
if ((node.effectTag & Placement) !== NoEffect) {
|
|
return MOUNTING;
|
|
}
|
|
while (node.return) {
|
|
node = node.return;
|
|
if ((node.effectTag & Placement) !== NoEffect) {
|
|
return MOUNTING;
|
|
}
|
|
}
|
|
} else {
|
|
while (node.return) {
|
|
node = node.return;
|
|
}
|
|
}
|
|
if (node.tag === HostRoot) {
|
|
// TODO: Check if this was a nested HostRoot when used with
|
|
// renderContainerIntoSubtree.
|
|
return MOUNTED;
|
|
}
|
|
// If we didn't hit the root, that means that we're in an disconnected tree
|
|
// that has been unmounted.
|
|
return UNMOUNTED;
|
|
}
|
|
|
|
function isFiberMounted(fiber) {
|
|
return isFiberMountedImpl(fiber) === MOUNTED;
|
|
}
|
|
|
|
function isMounted(component) {
|
|
{
|
|
var owner = ReactCurrentOwner.current;
|
|
if (owner !== null && owner.tag === ClassComponent) {
|
|
var ownerFiber = owner;
|
|
var instance = ownerFiber.stateNode;
|
|
!instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
|
|
instance._warnedAboutRefsInRender = true;
|
|
}
|
|
}
|
|
|
|
var fiber = get(component);
|
|
if (!fiber) {
|
|
return false;
|
|
}
|
|
return isFiberMountedImpl(fiber) === MOUNTED;
|
|
}
|
|
|
|
function assertIsMounted(fiber) {
|
|
!(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
|
|
}
|
|
|
|
function findCurrentFiberUsingSlowPath(fiber) {
|
|
var alternate = fiber.alternate;
|
|
if (!alternate) {
|
|
// If there is no alternate, then we only need to check if it is mounted.
|
|
var state = isFiberMountedImpl(fiber);
|
|
!(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
|
|
if (state === MOUNTING) {
|
|
return null;
|
|
}
|
|
return fiber;
|
|
}
|
|
// If we have two possible branches, we'll walk backwards up to the root
|
|
// to see what path the root points to. On the way we may hit one of the
|
|
// special cases and we'll deal with them.
|
|
var a = fiber;
|
|
var b = alternate;
|
|
while (true) {
|
|
var parentA = a.return;
|
|
var parentB = parentA ? parentA.alternate : null;
|
|
if (!parentA || !parentB) {
|
|
// We're at the root.
|
|
break;
|
|
}
|
|
|
|
// If both copies of the parent fiber point to the same child, we can
|
|
// assume that the child is current. This happens when we bailout on low
|
|
// priority: the bailed out fiber's child reuses the current child.
|
|
if (parentA.child === parentB.child) {
|
|
var child = parentA.child;
|
|
while (child) {
|
|
if (child === a) {
|
|
// We've determined that A is the current branch.
|
|
assertIsMounted(parentA);
|
|
return fiber;
|
|
}
|
|
if (child === b) {
|
|
// We've determined that B is the current branch.
|
|
assertIsMounted(parentA);
|
|
return alternate;
|
|
}
|
|
child = child.sibling;
|
|
}
|
|
// We should never have an alternate for any mounting node. So the only
|
|
// way this could possibly happen is if this was unmounted, if at all.
|
|
invariant(false, 'Unable to find node on an unmounted component.');
|
|
}
|
|
|
|
if (a.return !== b.return) {
|
|
// The return pointer of A and the return pointer of B point to different
|
|
// fibers. We assume that return pointers never criss-cross, so A must
|
|
// belong to the child set of A.return, and B must belong to the child
|
|
// set of B.return.
|
|
a = parentA;
|
|
b = parentB;
|
|
} else {
|
|
// The return pointers point to the same fiber. We'll have to use the
|
|
// default, slow path: scan the child sets of each parent alternate to see
|
|
// which child belongs to which set.
|
|
//
|
|
// Search parent A's child set
|
|
var didFindChild = false;
|
|
var _child = parentA.child;
|
|
while (_child) {
|
|
if (_child === a) {
|
|
didFindChild = true;
|
|
a = parentA;
|
|
b = parentB;
|
|
break;
|
|
}
|
|
if (_child === b) {
|
|
didFindChild = true;
|
|
b = parentA;
|
|
a = parentB;
|
|
break;
|
|
}
|
|
_child = _child.sibling;
|
|
}
|
|
if (!didFindChild) {
|
|
// Search parent B's child set
|
|
_child = parentB.child;
|
|
while (_child) {
|
|
if (_child === a) {
|
|
didFindChild = true;
|
|
a = parentB;
|
|
b = parentA;
|
|
break;
|
|
}
|
|
if (_child === b) {
|
|
didFindChild = true;
|
|
b = parentB;
|
|
a = parentA;
|
|
break;
|
|
}
|
|
_child = _child.sibling;
|
|
}
|
|
!didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
|
|
}
|
|
}
|
|
|
|
!(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
|
|
}
|
|
// If the root is not a host container, we're in a disconnected tree. I.e.
|
|
// unmounted.
|
|
!(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
|
|
if (a.stateNode.current === a) {
|
|
// We've determined that A is the current branch.
|
|
return fiber;
|
|
}
|
|
// Otherwise B has to be current branch.
|
|
return alternate;
|
|
}
|
|
|
|
function findCurrentHostFiber(parent) {
|
|
var currentParent = findCurrentFiberUsingSlowPath(parent);
|
|
if (!currentParent) {
|
|
return null;
|
|
}
|
|
|
|
// Next we'll drill down this component to find the first HostComponent/Text.
|
|
var node = currentParent;
|
|
while (true) {
|
|
if (node.tag === HostComponent || node.tag === HostText) {
|
|
return node;
|
|
} else if (node.child) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === currentParent) {
|
|
return null;
|
|
}
|
|
while (!node.sibling) {
|
|
if (!node.return || node.return === currentParent) {
|
|
return null;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
// Flow needs the return null here, but ESLint complains about it.
|
|
// eslint-disable-next-line no-unreachable
|
|
return null;
|
|
}
|
|
|
|
function findCurrentHostFiberWithNoPortals(parent) {
|
|
var currentParent = findCurrentFiberUsingSlowPath(parent);
|
|
if (!currentParent) {
|
|
return null;
|
|
}
|
|
|
|
// Next we'll drill down this component to find the first HostComponent/Text.
|
|
var node = currentParent;
|
|
while (true) {
|
|
if (node.tag === HostComponent || node.tag === HostText) {
|
|
return node;
|
|
} else if (node.child && node.tag !== HostPortal) {
|
|
node.child.return = node;
|
|
node = node.child;
|
|
continue;
|
|
}
|
|
if (node === currentParent) {
|
|
return null;
|
|
}
|
|
while (!node.sibling) {
|
|
if (!node.return || node.return === currentParent) {
|
|
return null;
|
|
}
|
|
node = node.return;
|
|
}
|
|
node.sibling.return = node.return;
|
|
node = node.sibling;
|
|
}
|
|
// Flow needs the return null here, but ESLint complains about it.
|
|
// eslint-disable-next-line no-unreachable
|
|
return null;
|
|
}
|
|
|
|
exports.isFiberMounted = isFiberMounted;
|
|
exports.isMounted = isMounted;
|
|
exports.findCurrentFiberUsingSlowPath = findCurrentFiberUsingSlowPath;
|
|
exports.findCurrentHostFiber = findCurrentHostFiber;
|
|
exports.findCurrentHostFiberWithNoPortals = findCurrentHostFiberWithNoPortals;
|
|
})();
|
|
}
|