2017-05-03 15:35:00 +02:00
/ * *
* 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 .
*
* /
'use strict' ;
var _prodInvariant = require ( './reactProdInvariant' ) ,
_assign = require ( 'object-assign' ) ;
var ReactCompositeComponent = require ( './ReactCompositeComponent' ) ;
var ReactEmptyComponent = require ( './ReactEmptyComponent' ) ;
var ReactHostComponent = require ( './ReactHostComponent' ) ;
var getNextDebugID = require ( 'react/lib/getNextDebugID' ) ;
var invariant = require ( 'fbjs/lib/invariant' ) ;
var warning = require ( 'fbjs/lib/warning' ) ;
// To avoid a cyclic dependency, we create the final class in this module
var ReactCompositeComponentWrapper = function ( element ) {
this . construct ( element ) ;
} ;
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' ;
}
/ * *
* 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 ;
var type = element . type ;
if ( typeof type !== 'function' && typeof type !== 'string' ) {
var info = '' ;
if ( process . env . NODE _ENV !== 'production' ) {
if ( type === undefined || typeof type === 'object' && type !== null && Object . keys ( type ) . length === 0 ) {
2017-08-14 05:01:11 +02:00
info += ' You likely forgot to export your component from the file ' + "it's defined in." ;
2017-05-03 15:35:00 +02:00
}
}
info += getDeclarationErrorAddendum ( element . _owner ) ;
! false ? process . env . NODE _ENV !== 'production' ? invariant ( false , 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s' , type == null ? type : typeof type , info ) : _prodInvariant ( '130' , type == null ? type : typeof type , info ) : void 0 ;
}
// 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 {
! false ? process . env . NODE _ENV !== 'production' ? invariant ( false , 'Encountered invalid React node of type %s' , typeof node ) : _prodInvariant ( '131' , typeof node ) : void 0 ;
}
if ( process . env . NODE _ENV !== 'production' ) {
process . env . NODE _ENV !== 'production' ? warning ( typeof instance . mountComponent === 'function' && typeof instance . receiveComponent === 'function' && typeof instance . getHostNode === 'function' && typeof instance . unmountComponent === 'function' , 'Only React Components can be mounted.' ) : void 0 ;
}
// 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 ( process . env . NODE _ENV !== 'production' ) {
instance . _debugID = shouldHaveDebugID ? getNextDebugID ( ) : 0 ;
}
// Internal instances should fully constructed at this point, so they should
// not get any new fields added to them at this point.
if ( process . env . NODE _ENV !== 'production' ) {
if ( Object . preventExtensions ) {
Object . preventExtensions ( instance ) ;
}
}
return instance ;
}
_assign ( ReactCompositeComponentWrapper . prototype , ReactCompositeComponent , {
_instantiateReactComponent : instantiateReactComponent
} ) ;
module . exports = instantiateReactComponent ;