UNPKG

20.6 kBJavaScriptView Raw
1/** @license React v0.22.0
2 * react-reconciler-reflection.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18Object.defineProperty(exports, '__esModule', { value: true });
19
20var React = require('react');
21
22// Do not require this module directly! Use normal `invariant` calls with
23// template literal strings. The messages will be converted to ReactError during
24// build, and in production they will be minified.
25
26// Do not require this module directly! Use normal `invariant` calls with
27// template literal strings. The messages will be converted to ReactError during
28// build, and in production they will be minified.
29function ReactError(error) {
30 error.name = 'Invariant Violation';
31 return error;
32}
33
34/**
35 * Use invariant() to assert state which your program assumes to be true.
36 *
37 * Provide sprintf-style format (only %s is supported) and arguments
38 * to provide information about what broke and what you were
39 * expecting.
40 *
41 * The invariant message will be stripped in production, but the invariant
42 * will remain to ensure logic does not differ in production.
43 */
44
45/**
46 * Similar to invariant but only logs a warning if the condition is not met.
47 * This can be used to log issues in development environments in critical
48 * paths. Removing the logging code for production environments will keep the
49 * same logic and follow the same code paths.
50 */
51var warningWithoutStack = function () {};
52
53{
54 warningWithoutStack = function (condition, format) {
55 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
56 args[_key - 2] = arguments[_key];
57 }
58
59 if (format === undefined) {
60 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
61 }
62
63 if (args.length > 8) {
64 // Check before the condition to catch violations early.
65 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
66 }
67
68 if (condition) {
69 return;
70 }
71
72 if (typeof console !== 'undefined') {
73 var argsWithFormat = args.map(function (item) {
74 return '' + item;
75 });
76 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
77 // breaks IE9: https://github.com/facebook/react/issues/13610
78
79 Function.prototype.apply.call(console.error, console, argsWithFormat);
80 }
81
82 try {
83 // --- Welcome to debugging React ---
84 // This error was thrown as a convenience so that you can use this stack
85 // to find the callsite that caused this warning to fire.
86 var argIndex = 0;
87 var message = 'Warning: ' + format.replace(/%s/g, function () {
88 return args[argIndex++];
89 });
90 throw new Error(message);
91 } catch (x) {}
92 };
93}
94
95var warningWithoutStack$1 = warningWithoutStack;
96
97/**
98 * `ReactInstanceMap` maintains a mapping from a public facing stateful
99 * instance (key) and the internal representation (value). This allows public
100 * methods to accept the user facing instance as an argument and map them back
101 * to internal methods.
102 *
103 * Note that this module is currently shared and assumed to be stateless.
104 * If this becomes an actual Map, that will break.
105 */
106
107/**
108 * This API should be called `delete` but we'd have to make sure to always
109 * transform these to strings for IE support. When this transform is fully
110 * supported we can rename it.
111 */
112
113function get(key) {
114 return key._reactInternalFiber;
115}
116
117var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
118// Current owner and dispatcher used to share the same ref,
119// but PR #14548 split them out to better support the react-debug-tools package.
120
121if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
122 ReactSharedInternals.ReactCurrentDispatcher = {
123 current: null
124 };
125}
126
127if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
128 ReactSharedInternals.ReactCurrentBatchConfig = {
129 suspense: null
130 };
131}
132
133// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
134// nor polyfill, then a plain number is used for performance.
135var hasSymbol = typeof Symbol === 'function' && Symbol.for;
136
137var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
138var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
139var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
140var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
141var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
142var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
143// (unstable) APIs that have been removed. Can we remove the symbols?
144
145
146
147var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
148var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
149var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
150var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
151var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
152
153{
154
155}
156
157var Resolved = 1;
158
159function refineResolvedLazyComponent(lazyComponent) {
160 return lazyComponent._status === Resolved ? lazyComponent._result : null;
161}
162
163function getWrappedName(outerType, innerType, wrapperName) {
164 var functionName = innerType.displayName || innerType.name || '';
165 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
166}
167
168function getComponentName(type) {
169 if (type == null) {
170 // Host root, text node or just invalid type.
171 return null;
172 }
173
174 {
175 if (typeof type.tag === 'number') {
176 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
177 }
178 }
179
180 if (typeof type === 'function') {
181 return type.displayName || type.name || null;
182 }
183
184 if (typeof type === 'string') {
185 return type;
186 }
187
188 switch (type) {
189 case REACT_FRAGMENT_TYPE:
190 return 'Fragment';
191
192 case REACT_PORTAL_TYPE:
193 return 'Portal';
194
195 case REACT_PROFILER_TYPE:
196 return "Profiler";
197
198 case REACT_STRICT_MODE_TYPE:
199 return 'StrictMode';
200
201 case REACT_SUSPENSE_TYPE:
202 return 'Suspense';
203
204 case REACT_SUSPENSE_LIST_TYPE:
205 return 'SuspenseList';
206 }
207
208 if (typeof type === 'object') {
209 switch (type.$$typeof) {
210 case REACT_CONTEXT_TYPE:
211 return 'Context.Consumer';
212
213 case REACT_PROVIDER_TYPE:
214 return 'Context.Provider';
215
216 case REACT_FORWARD_REF_TYPE:
217 return getWrappedName(type, type.render, 'ForwardRef');
218
219 case REACT_MEMO_TYPE:
220 return getComponentName(type.type);
221
222 case REACT_LAZY_TYPE:
223 {
224 var thenable = type;
225 var resolvedThenable = refineResolvedLazyComponent(thenable);
226
227 if (resolvedThenable) {
228 return getComponentName(resolvedThenable);
229 }
230
231 break;
232 }
233 }
234 }
235
236 return null;
237}
238
239var ClassComponent = 1;
240 // Before we know whether it is function or class
241
242var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
243
244var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
245
246var HostComponent = 5;
247var HostText = 6;
248
249
250
251
252
253
254var SuspenseComponent = 13;
255
256
257
258
259
260
261var FundamentalComponent = 20;
262
263// Don't change these two values. They're used by React Dev Tools.
264var NoEffect =
265/* */
2660;
267 // You can change the rest (and add more).
268
269var Placement =
270/* */
2712;
272
273
274
275
276
277
278
279
280
281var Hydrating =
282/* */
2831024;
284 // Passive & Update & Callback & Ref & Snapshot
285
286 // Union of all host effects
287
288// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
289
290 // In some cases, StrictMode should also double-render lifecycles.
291// This can be confusing for tests though,
292// And it can be bad for performance in production.
293// This feature flag can be used to control the behavior:
294
295 // To preserve the "Pause on caught exceptions" behavior of the debugger, we
296// replay the begin phase of a failed component inside invokeGuardedCallback.
297
298 // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
299
300 // Gather advanced timing metrics for Profiler subtrees.
301
302 // Trace which interactions trigger each commit.
303
304 // Only used in www builds.
305
306 // TODO: true? Here it might just be false.
307
308 // Only used in www builds.
309
310 // Only used in www builds.
311
312 // Disable javascript: URL strings in href for XSS protection.
313
314 // React Fire: prevent the value and checked attributes from syncing
315// with their related DOM properties
316
317 // These APIs will no longer be "unstable" in the upcoming 16.7 release,
318// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
319
320
321 // See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
322// This is a flag so we can fix warnings in RN core before turning it on
323
324 // Experimental React Flare event system and event components support.
325
326 // Experimental Host Component support.
327
328var enableFundamentalAPI = false; // Experimental Scope support.
329
330 // New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
331
332 // We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
333// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
334
335 // For tests, we flush suspense fallbacks in an act scope;
336// *except* in some of our own tests, where we test incremental loading states.
337
338 // Changes priority of some events like mousemove to user-blocking priority,
339// but without making them discrete. The flag exists in case it causes
340// starvation problems.
341
342 // Add a callback property to suspense to notify which promises are currently
343// in the update queue. This allows reporting and tracing of what is causing
344// the user to see a loading state.
345// Also allows hydration callbacks to fire when a dehydrated boundary gets
346// hydrated or deleted.
347
348 // Part of the simplification of React.createElement so we can eventually move
349// from React.createElement to React.jsx
350// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
351
352var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
353function getNearestMountedFiber(fiber) {
354 var node = fiber;
355 var nearestMounted = fiber;
356
357 if (!fiber.alternate) {
358 // If there is no alternate, this might be a new tree that isn't inserted
359 // yet. If it is, then it will have a pending insertion effect on it.
360 var nextNode = node;
361
362 do {
363 node = nextNode;
364
365 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
366 // This is an insertion or in-progress hydration. The nearest possible
367 // mounted fiber is the parent but we need to continue to figure out
368 // if that one is still mounted.
369 nearestMounted = node.return;
370 }
371
372 nextNode = node.return;
373 } while (nextNode);
374 } else {
375 while (node.return) {
376 node = node.return;
377 }
378 }
379
380 if (node.tag === HostRoot) {
381 // TODO: Check if this was a nested HostRoot when used with
382 // renderContainerIntoSubtree.
383 return nearestMounted;
384 } // If we didn't hit the root, that means that we're in an disconnected tree
385 // that has been unmounted.
386
387
388 return null;
389}
390function getSuspenseInstanceFromFiber(fiber) {
391 if (fiber.tag === SuspenseComponent) {
392 var suspenseState = fiber.memoizedState;
393
394 if (suspenseState === null) {
395 var current = fiber.alternate;
396
397 if (current !== null) {
398 suspenseState = current.memoizedState;
399 }
400 }
401
402 if (suspenseState !== null) {
403 return suspenseState.dehydrated;
404 }
405 }
406
407 return null;
408}
409function getContainerFromFiber(fiber) {
410 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
411}
412function isFiberMounted(fiber) {
413 return getNearestMountedFiber(fiber) === fiber;
414}
415function isMounted(component) {
416 {
417 var owner = ReactCurrentOwner.current;
418
419 if (owner !== null && owner.tag === ClassComponent) {
420 var ownerFiber = owner;
421 var instance = ownerFiber.stateNode;
422 !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;
423 instance._warnedAboutRefsInRender = true;
424 }
425 }
426
427 var fiber = get(component);
428
429 if (!fiber) {
430 return false;
431 }
432
433 return getNearestMountedFiber(fiber) === fiber;
434}
435
436function assertIsMounted(fiber) {
437 (function () {
438 if (!(getNearestMountedFiber(fiber) === fiber)) {
439 {
440 throw ReactError(Error("Unable to find node on an unmounted component."));
441 }
442 }
443 })();
444}
445
446function findCurrentFiberUsingSlowPath(fiber) {
447 var alternate = fiber.alternate;
448
449 if (!alternate) {
450 // If there is no alternate, then we only need to check if it is mounted.
451 var nearestMounted = getNearestMountedFiber(fiber);
452
453 (function () {
454 if (!(nearestMounted !== null)) {
455 {
456 throw ReactError(Error("Unable to find node on an unmounted component."));
457 }
458 }
459 })();
460
461 if (nearestMounted !== fiber) {
462 return null;
463 }
464
465 return fiber;
466 } // If we have two possible branches, we'll walk backwards up to the root
467 // to see what path the root points to. On the way we may hit one of the
468 // special cases and we'll deal with them.
469
470
471 var a = fiber;
472 var b = alternate;
473
474 while (true) {
475 var parentA = a.return;
476
477 if (parentA === null) {
478 // We're at the root.
479 break;
480 }
481
482 var parentB = parentA.alternate;
483
484 if (parentB === null) {
485 // There is no alternate. This is an unusual case. Currently, it only
486 // happens when a Suspense component is hidden. An extra fragment fiber
487 // is inserted in between the Suspense fiber and its children. Skip
488 // over this extra fragment fiber and proceed to the next parent.
489 var nextParent = parentA.return;
490
491 if (nextParent !== null) {
492 a = b = nextParent;
493 continue;
494 } // If there's no parent, we're at the root.
495
496
497 break;
498 } // If both copies of the parent fiber point to the same child, we can
499 // assume that the child is current. This happens when we bailout on low
500 // priority: the bailed out fiber's child reuses the current child.
501
502
503 if (parentA.child === parentB.child) {
504 var child = parentA.child;
505
506 while (child) {
507 if (child === a) {
508 // We've determined that A is the current branch.
509 assertIsMounted(parentA);
510 return fiber;
511 }
512
513 if (child === b) {
514 // We've determined that B is the current branch.
515 assertIsMounted(parentA);
516 return alternate;
517 }
518
519 child = child.sibling;
520 } // We should never have an alternate for any mounting node. So the only
521 // way this could possibly happen is if this was unmounted, if at all.
522
523
524 (function () {
525 {
526 {
527 throw ReactError(Error("Unable to find node on an unmounted component."));
528 }
529 }
530 })();
531 }
532
533 if (a.return !== b.return) {
534 // The return pointer of A and the return pointer of B point to different
535 // fibers. We assume that return pointers never criss-cross, so A must
536 // belong to the child set of A.return, and B must belong to the child
537 // set of B.return.
538 a = parentA;
539 b = parentB;
540 } else {
541 // The return pointers point to the same fiber. We'll have to use the
542 // default, slow path: scan the child sets of each parent alternate to see
543 // which child belongs to which set.
544 //
545 // Search parent A's child set
546 var didFindChild = false;
547 var _child = parentA.child;
548
549 while (_child) {
550 if (_child === a) {
551 didFindChild = true;
552 a = parentA;
553 b = parentB;
554 break;
555 }
556
557 if (_child === b) {
558 didFindChild = true;
559 b = parentA;
560 a = parentB;
561 break;
562 }
563
564 _child = _child.sibling;
565 }
566
567 if (!didFindChild) {
568 // Search parent B's child set
569 _child = parentB.child;
570
571 while (_child) {
572 if (_child === a) {
573 didFindChild = true;
574 a = parentB;
575 b = parentA;
576 break;
577 }
578
579 if (_child === b) {
580 didFindChild = true;
581 b = parentB;
582 a = parentA;
583 break;
584 }
585
586 _child = _child.sibling;
587 }
588
589 (function () {
590 if (!didFindChild) {
591 {
592 throw ReactError(Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."));
593 }
594 }
595 })();
596 }
597 }
598
599 (function () {
600 if (!(a.alternate === b)) {
601 {
602 throw ReactError(Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."));
603 }
604 }
605 })();
606 } // If the root is not a host container, we're in a disconnected tree. I.e.
607 // unmounted.
608
609
610 (function () {
611 if (!(a.tag === HostRoot)) {
612 {
613 throw ReactError(Error("Unable to find node on an unmounted component."));
614 }
615 }
616 })();
617
618 if (a.stateNode.current === a) {
619 // We've determined that A is the current branch.
620 return fiber;
621 } // Otherwise B has to be current branch.
622
623
624 return alternate;
625}
626function findCurrentHostFiber(parent) {
627 var currentParent = findCurrentFiberUsingSlowPath(parent);
628
629 if (!currentParent) {
630 return null;
631 } // Next we'll drill down this component to find the first HostComponent/Text.
632
633
634 var node = currentParent;
635
636 while (true) {
637 if (node.tag === HostComponent || node.tag === HostText) {
638 return node;
639 } else if (node.child) {
640 node.child.return = node;
641 node = node.child;
642 continue;
643 }
644
645 if (node === currentParent) {
646 return null;
647 }
648
649 while (!node.sibling) {
650 if (!node.return || node.return === currentParent) {
651 return null;
652 }
653
654 node = node.return;
655 }
656
657 node.sibling.return = node.return;
658 node = node.sibling;
659 } // Flow needs the return null here, but ESLint complains about it.
660 // eslint-disable-next-line no-unreachable
661
662
663 return null;
664}
665function findCurrentHostFiberWithNoPortals(parent) {
666 var currentParent = findCurrentFiberUsingSlowPath(parent);
667
668 if (!currentParent) {
669 return null;
670 } // Next we'll drill down this component to find the first HostComponent/Text.
671
672
673 var node = currentParent;
674
675 while (true) {
676 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI && node.tag === FundamentalComponent) {
677 return node;
678 } else if (node.child && node.tag !== HostPortal) {
679 node.child.return = node;
680 node = node.child;
681 continue;
682 }
683
684 if (node === currentParent) {
685 return null;
686 }
687
688 while (!node.sibling) {
689 if (!node.return || node.return === currentParent) {
690 return null;
691 }
692
693 node = node.return;
694 }
695
696 node.sibling.return = node.return;
697 node = node.sibling;
698 } // Flow needs the return null here, but ESLint complains about it.
699 // eslint-disable-next-line no-unreachable
700
701
702 return null;
703}
704
705exports.getNearestMountedFiber = getNearestMountedFiber;
706exports.getSuspenseInstanceFromFiber = getSuspenseInstanceFromFiber;
707exports.getContainerFromFiber = getContainerFromFiber;
708exports.isFiberMounted = isFiberMounted;
709exports.isMounted = isMounted;
710exports.findCurrentFiberUsingSlowPath = findCurrentFiberUsingSlowPath;
711exports.findCurrentHostFiber = findCurrentHostFiber;
712exports.findCurrentHostFiberWithNoPortals = findCurrentHostFiberWithNoPortals;
713 })();
714}