Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| /** | |
| * Copyright 2013-present, Facebook, Inc. | |
| * All rights reserved. | |
| * | |
| * This source code is licensed under the BSD-style license found in the | |
| * LICENSE file in the root directory of this source tree. An additional grant | |
| * of patent rights can be found in the PATENTS file in the same directory. | |
| * | |
| * @providesModule instantiateReactComponent | |
| */ | |
| 'use strict'; | |
| var ReactCompositeComponent = require('ReactCompositeComponent'); | |
| var ReactEmptyComponent = require('ReactEmptyComponent'); | |
| var ReactHostComponent = require('ReactHostComponent'); | |
| var invariant = require('invariant'); | |
| var warning = require('warning'); | |
| // To avoid a cyclic dependency, we create the final class in this module | |
| var ReactCompositeComponentWrapper = function(element) { | |
| this.construct(element); | |
| }; | |
| Object.assign( | |
| ReactCompositeComponentWrapper.prototype, | |
| ReactCompositeComponent, | |
| { | |
| _instantiateReactComponent: instantiateReactComponent, | |
| } | |
| ); | |
| function getDeclarationErrorAddendum(owner) { | |
| if (owner) { | |
| var name = owner.getName(); | |
| if (name) { | |
| return ' Check the render method of `' + name + '`.'; | |
| } | |
| } | |
| return ''; | |
| } | |
| /** | |
| * Check if the type reference is a known internal type. I.e. not a user | |
| * provided composite type. | |
| * | |
| * @param {function} type | |
| * @return {boolean} Returns true if this is a valid internal type. | |
| */ | |
| function isInternalComponentType(type) { | |
| return ( | |
| typeof type === 'function' && | |
| typeof type.prototype !== 'undefined' && | |
| typeof type.prototype.mountComponent === 'function' && | |
| typeof type.prototype.receiveComponent === 'function' | |
| ); | |
| } | |
| var nextDebugID = 1; | |
| /** | |
| * Given a ReactNode, create an instance that will actually be mounted. | |
| * | |
| * @param {ReactNode} node | |
| * @param {boolean} shouldHaveDebugID | |
| * @return {object} A new instance of the element's constructor. | |
| * @protected | |
| */ | |
| function instantiateReactComponent(node, shouldHaveDebugID) { | |
| var instance; | |
| if (node === null || node === false) { | |
| instance = ReactEmptyComponent.create(instantiateReactComponent); | |
| } else if (typeof node === 'object') { | |
| var element = node; | |
| invariant( | |
| element && (typeof element.type === 'function' || | |
| typeof element.type === 'string'), | |
| 'Element type is invalid: expected a string (for built-in components) ' + | |
| 'or a class/function (for composite components) but got: %s.%s', | |
| element.type == null ? element.type : typeof element.type, | |
| getDeclarationErrorAddendum(element._owner) | |
| ); | |
| // Special case string values | |
| if (typeof element.type === 'string') { | |
| instance = ReactHostComponent.createInternalComponent(element); | |
| } else if (isInternalComponentType(element.type)) { | |
| // This is temporarily available for custom components that are not string | |
| // representations. I.e. ART. Once those are updated to use the string | |
| // representation, we can drop this code path. | |
| instance = new element.type(element); | |
| // We renamed this. Allow the old name for compat. :( | |
| if (!instance.getHostNode) { | |
| instance.getHostNode = instance.getNativeNode; | |
| } | |
| } else { | |
| instance = new ReactCompositeComponentWrapper(element); | |
| } | |
| } else if (typeof node === 'string' || typeof node === 'number') { | |
| instance = ReactHostComponent.createInstanceForText(node); | |
| } else { | |
| invariant( | |
| false, | |
| 'Encountered invalid React node of type %s', | |
| typeof node | |
| ); | |
| } | |
| if (__DEV__) { | |
| warning( | |
| typeof instance.mountComponent === 'function' && | |
| typeof instance.receiveComponent === 'function' && | |
| typeof instance.getHostNode === 'function' && | |
| typeof instance.unmountComponent === 'function', | |
| 'Only React Components can be mounted.' | |
| ); | |
| } | |
| // These two fields are used by the DOM and ART diffing algorithms | |
| // respectively. Instead of using expandos on components, we should be | |
| // storing the state needed by the diffing algorithms elsewhere. | |
| instance._mountIndex = 0; | |
| instance._mountImage = null; | |
| if (__DEV__) { | |
| instance._debugID = shouldHaveDebugID ? nextDebugID++ : 0; | |
| } | |
| // Internal instances should fully constructed at this point, so they should | |
| // not get any new fields added to them at this point. | |
| if (__DEV__) { | |
| if (Object.preventExtensions) { | |
| Object.preventExtensions(instance); | |
| } | |
| } | |
| return instance; | |
| } | |
| module.exports = instantiateReactComponent; |