/** * Ensure that every element either is passed in a static location, in an * array with an explicit keys property defined, or in an object literal * with valid key property. * * @internal * @param {ReactNode} node Statically passed child of any type. * @param {*} parentType node's parent's type. */ function validateChildKeys(node, parentType) { if (typeof node !== 'object') { return; } if (Array.isArray(node)) { for (var i = 0; i < node.length; i++) { var child = node[i]; if (ReactElement.isValidElement(child)) { validateExplicitKey(child, parentType); } } } else if (ReactElement.isValidElement(node)) { // This element was passed in a valid location. if (node._store) { node._store.validated = true; } } else if (node) { var iteratorFn = getIteratorFn(node); // Entry iterators provide implicit keys. if (iteratorFn) { if (iteratorFn !== node.entries) { var iterator = iteratorFn.call(node); var step; while (!(step = iterator.next()).done) { if (ReactElement.isValidElement(step.value)) { validateExplicitKey(step.value, parentType); } } } } } }
function isNode(propValue) { switch (typeof propValue) { case 'number': case 'string': case 'undefined': return true; case 'boolean': return !propValue; case 'object': if (Array.isArray(propValue)) { return propValue.every(isNode); } if (propValue === null || ReactElement.isValidElement(propValue)) { return true; } propValue = ReactFragment.extractIfFragment(propValue); for (var k in propValue) { if (!isNode(propValue[k])) { return false; } } return true; default: return false; } }
/** * Returns the first child in a collection of children and verifies that there * is only one child in the collection. The current implementation of this * function assumes that a single child gets passed without a wrapper, but the * purpose of this helper function is to abstract away the particular structure * of children. * * @param {?object} children Child collection structure. * @return {ReactComponent} The first and only `ReactComponent` contained in the * structure. */ function onlyChild(children) { invariant( ReactElement.isValidElement(children), 'onlyChild must be passed a children with exactly one child.' ); return children; }
ReactShallowRenderer.prototype.render = function(element, context) { // Ensure we've done the default injections. This might not be true in the // case of a simple test that only requires React and the TestUtils in // conjunction with an inline-requires transform. ReactDefaultInjection.inject(); invariant( ReactElement.isValidElement(element), 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '' ); invariant( typeof element.type !== 'string', 'ReactShallowRenderer render(): Shallow rendering works only with custom ' + 'components, not primitives (%s). Instead of calling `.render(el)` and ' + 'inspecting the rendered output, look at `el.props` directly instead.', element.type ); if (!context) { context = emptyObject; } ReactUpdates.batchedUpdates(_batchedRender, this, element, context); return this.getRenderOutput(); };
function isRenderable(propValue) { switch(typeof propValue) { // TODO: this was probably written with the assumption that we're not // returning `this.props.component` directly from `render`. This is // currently not supported but we should, to make it consistent. case 'number': case 'string': return true; case 'boolean': return !propValue; case 'object': if (Array.isArray(propValue)) { return propValue.every(isRenderable); } if (ReactElement.isValidElement(propValue)) { return true; } for (var k in propValue) { if (!isRenderable(propValue[k])) { return false; } } return true; default: return false; } }
function renderToString(element) { invariant( ReactElement.isValidElement(element), 'renderToString(): You must pass a valid ReactElement.' ); return renderToStringImpl(element, false); }
function() { var renderedComponent; var previousContext = ReactContext.current; ReactContext.current = this._processChildContext( this._currentElement._context ); ReactCurrentOwner.current = this; try { renderedComponent = this.render(); if (renderedComponent === null || renderedComponent === false) { renderedComponent = ReactEmptyComponent.getEmptyComponent(); ReactEmptyComponent.registerNullComponentID(this._rootNodeID); } else { ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID); } } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null; } invariant( ReactElement.isValidElement(renderedComponent), '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.constructor.displayName || 'ReactCompositeComponent' ); return renderedComponent; }
_renderValidatedComponent: function() { var renderedComponent; if (__DEV__ || !(this._instance instanceof StatelessComponent)) { ReactCurrentOwner.current = this; try { renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); } finally { ReactCurrentOwner.current = null; } } else { renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); } invariant( // TODO: An `isValidNode` function would probably be more appropriate renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent), '%s.render(): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent' ); return renderedComponent; },
ReactShallowRenderer.prototype.render = function(element, context) { invariant( ReactElement.isValidElement(element), 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '' ); invariant( typeof element.type !== 'string', 'ReactShallowRenderer render(): Shallow rendering works only with custom ' + 'components, not primitives (%s). Instead of calling `.render(el)` and ' + 'inspecting the rendered output, look at `el.props` directly instead.', element.type ); if (!context) { context = emptyObject; } var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(true); this._render(element, transaction, context); ReactUpdates.ReactReconcileTransaction.release(transaction); return this.getRenderOutput(); };
function renderToStaticMarkup(element) { invariant( ReactElement.isValidElement(element), 'renderToStaticMarkup(): You must pass a valid ReactElement.' ); return renderToStringImpl(element, true); }
function mapSingleChildIntoContext(bookKeeping, child, childKey) { var {result, keyPrefix, func, context} = bookKeeping; var mappedChild = func.call(context, child, bookKeeping.count++); if (Array.isArray(mappedChild)) { mapIntoWithKeyPrefixInternal( mappedChild, result, childKey, emptyFunction.thatReturnsArgument, ); } else if (mappedChild != null) { if (ReactElement.isValidElement(mappedChild)) { mappedChild = ReactElement.cloneAndReplaceKey( mappedChild, // Keep both the (mapped) and old keys if they differ, just as // traverseAllChildren used to do for objects as children keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey, ); } result.push(mappedChild); } }
function findAllInRenderedTreeInternal(inst, test) { if (!inst || !inst.getPublicInstance) { return []; } var publicInst = inst.getPublicInstance(); var ret = test(publicInst) ? [publicInst] : []; var currentElement = inst._currentElement; if (ReactTestUtils.isDOMComponent(publicInst)) { var renderedChildren = inst._renderedChildren; var key; for (key in renderedChildren) { if (!renderedChildren.hasOwnProperty(key)) { continue; } ret = ret.concat( findAllInRenderedTreeInternal( renderedChildren[key], test ) ); } } else if ( ReactElement.isValidElement(currentElement) && typeof currentElement.type === 'function' ) { ret = ret.concat( findAllInRenderedTreeInternal(inst._renderedComponent, test) ); } return ret; }
/** * @param {ReactElement} element * @return {string} the HTML markup */ function renderToStringImpl(element, makeStaticMarkup) { invariant( ReactElement.isValidElement(element), 'renderToString(): You must pass a valid ReactElement.' ); var transaction; try { ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy); transaction = ReactServerRenderingTransaction.getPooled(makeStaticMarkup); return transaction.perform(function() { var componentInstance = instantiateReactComponent(element); var markup = componentInstance.mountComponent( transaction, null, ReactDOMContainerInfo(), emptyObject ); if (!makeStaticMarkup) { markup = ReactMarkupChecksum.addChecksumToMarkup(markup); } return markup; }, null); } finally { ReactServerRenderingTransaction.release(transaction); // Revert to the DOM batching strategy since these two renderers // currently share these stateful modules. ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy); } }
/** * Returns the first child in a collection of children and verifies that there * is only one child in the collection. * * See https://facebook.github.io/react/docs/react-api.html#react.children.only * * The current implementation of this function assumes that a single child gets * passed without a wrapper, but the purpose of this helper function is to * abstract away the particular structure of children. * * @param {?object} children Child collection structure. * @return {ReactElement} The first and only `ReactElement` contained in the * structure. */ function onlyChild(children) { invariant( ReactElement.isValidElement(children), 'React.Children.only expected to receive a single React element child.', ); return children; }
_renderValidatedComponent: function() { var renderedComponent; var previousContext = ReactContext.current; ReactContext.current = this._processChildContext( this._currentElement._context ); ReactCurrentOwner.current = this; var inst = this._instance; try { renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null; } invariant( // TODO: An `isValidNode` function would probably be more appropriate renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent), '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', inst.constructor.displayName || 'ReactCompositeComponent' ); return renderedComponent; },
/** * Ensure that every component either is passed in a static location, in an * array with an explicit keys property defined, or in an object literal * with valid key property. * * @internal * @param {*} component Statically passed child of any type. * @param {*} parentType component's parent's type. * @return {boolean} */ function validateChildKeys(component, parentType) { if (Array.isArray(component)) { for (var i = 0; i < component.length; i++) { var child = component[i]; if (ReactElement.isValidElement(child)) { validateExplicitKey(child, parentType); } } } else if (ReactElement.isValidElement(component)) { // This component was passed in a valid location. component._store.validated = true; } else if (component && typeof component === 'object') { monitorUseOfObjectMap(); for (var name in component) { validatePropertyKey(name, component[name], parentType); } } }
function validate(props, propName, componentName, location) { if (!ReactElement.isValidElement(props[propName])) { var locationName = ReactPropTypeLocationNames[location]; return new Error( `Invalid ${locationName} \`${propName}\` supplied to ` + `\`${componentName}\`, expected a React component.` ); } }
function warnIfInvalidElement(Component, element) { if (__DEV__) { warning( element === null || element === false || ReactElement.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component' ); } }
function validate(props, propName, componentName, location, propFullName) { var propValue = props[propName]; if (!ReactElement.isValidElement(propValue)) { var propType = getPropType(propValue); return new PropTypeError( `Invalid ${location} \`${propFullName}\` of type ` + `\`${propType}\` supplied to \`${componentName}\`, expected a single ReactElement.` ); } return null; }
function mixSpecIntoComponent(Constructor, spec) { if (!spec) { return; } invariant(!ReactLegacyElement.isValidFactory(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.'); invariant(!ReactElement.isValidElement(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.'); var proto = Constructor.prototype; if (spec.hasOwnProperty(MIXINS_KEY)) { RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); } for (var name in spec) { if (!spec.hasOwnProperty(name)) { continue; } if (name === MIXINS_KEY) { continue; } var property = spec[name]; validateMethodOverride(proto, name); if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { RESERVED_SPEC_KEYS[name](Constructor, property); } else { var isCompositeComponentMethod = ReactCompositeComponentInterface.hasOwnProperty(name); var isAlreadyDefined = proto.hasOwnProperty(name); var markedDontBind = property && property.__reactDontBind; var isFunction = typeof property === 'function'; var shouldAutoBind = isFunction && !isCompositeComponentMethod && !isAlreadyDefined && !markedDontBind; if (shouldAutoBind) { if (!proto.__reactAutoBindMap) { proto.__reactAutoBindMap = {}; } proto.__reactAutoBindMap[name] = property; proto[name] = property; } else { if (isAlreadyDefined) { var specPolicy = ReactCompositeComponentInterface[name]; invariant(isCompositeComponentMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY), 'ReactCompositeComponent: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name); if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { proto[name] = createMergedResultFunction(proto[name], property); } else if (specPolicy === SpecPolicy.DEFINE_MANY) { proto[name] = createChainedFunction(proto[name], property); } } else { proto[name] = property; if (__DEV__) { if (typeof property === 'function' && spec.displayName) { proto[name].displayName = spec.displayName + '_' + name; } } } } } } }
getType: function(node) { if (node === null || node === false) { return ReactNodeTypes.EMPTY; } else if (ReactElement.isValidElement(node)) { if (typeof node.type === 'function') { return ReactNodeTypes.COMPOSITE; } else { return ReactNodeTypes.HOST; } } invariant(false, 'Unexpected node: %s', node); },
isCompositeComponentElement: function(inst) { if (!ReactElement.isValidElement(inst)) { return false; } // We check the prototype of the type that will get mounted, not the // instance itself. This is a future proof way of duck typing. var prototype = inst.type.prototype; return ( typeof prototype.render === 'function' && typeof prototype.setState === 'function' ); },
function isNode(propValue) { switch (typeof propValue) { case 'number': case 'string': case 'undefined': return true; case 'boolean': return !propValue; case 'object': if (Array.isArray(propValue)) { return propValue.every(isNode); } if (propValue === null || ReactElement.isValidElement(propValue)) { return true; } var iteratorFn = getIteratorFn(propValue); if (iteratorFn) { var iterator = iteratorFn.call(propValue); var step; if (iteratorFn !== propValue.entries) { while (!(step = iterator.next()).done) { if (!isNode(step.value)) { return false; } } } else { // Iterator will provide entry [k,v] tuples rather than values. while (!(step = iterator.next()).done) { var entry = step.value; if (entry) { if (!isNode(entry[1])) { return false; } } } } } else { propValue = ReactFragment.extractIfFragment(propValue); for (var k in propValue) { if (!isNode(propValue[k])) { return false; } } } return true; default: return false; } }
function pushSingleChildToArray(traverseContext, child, name, i) { if (child == null) { return; } var result = traverseContext; if (ReactElement.isValidElement(child)) { child = ReactElement.cloneAndReplaceKey(child, name); } // For text components, leave unkeyed result.push(child); }
render: function(nextElement, container, callback) { invariant( ReactElement.isValidElement(nextElement), 'renderComponent(): Invalid component element.%s', ( typeof nextElement === 'string' ? ' Instead of passing an element string, make sure to instantiate ' + 'it by passing it to React.createElement.' : ReactLegacyElement.isValidFactory(nextElement) ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : // Check if it quacks like a element typeof nextElement.props !== "undefined" ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '' ) ); var prevComponent = instancesByReactRootID[getReactRootID(container)]; if (prevComponent) { var prevElement = prevComponent._currentElement; if (shouldUpdateReactComponent(prevElement, nextElement)) { return ReactMount._updateRootComponent( prevComponent, nextElement, container, callback ); } else { ReactMount.unmountComponentAtNode(container); } } var reactRootElement = getReactRootElementInContainer(container); var containerHasReactMarkup = reactRootElement && ReactMount.isRenderedByReact(reactRootElement); var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; var component = ReactMount._renderNewRootComponent( nextElement, container, shouldReuseMarkup ); callback && callback.call(component); return component; },
create: function(object) { if (typeof object !== 'object' || !object || Array.isArray(object)) { warning( false, 'React.addons.createFragment only accepts a single object. Got: %s', object ); return object; } if (ReactElement.isValidElement(object)) { warning( false, 'React.addons.createFragment does not accept a ReactElement ' + 'without a wrapper object.' ); return object; } invariant( object.nodeType !== 1, 'React.addons.createFragment(...): Encountered an invalid child; DOM ' + 'elements are not valid children of React components.' ); var result = []; for (var key in object) { if (__DEV__) { if (!warnedAboutNumeric && numericPropertyRegex.test(key)) { warning( false, 'React.addons.createFragment(...): Child objects should have ' + 'non-numeric keys so ordering is preserved.' ); warnedAboutNumeric = true; } } ReactChildren.mapIntoWithKeyPrefixInternal( object[key], result, key, emptyFunction.thatReturnsArgument ); } return result; },
/** * @param {ReactElement} element * @return {string} the HTML markup, without the extra React ID and checksum * (for generating static pages) */ function renderToStaticMarkup(element) { invariant( ReactElement.isValidElement(element), 'renderToStaticMarkup(): You must pass a valid ReactElement.' ); var transaction; try { var id = ReactInstanceHandles.createReactRootID(); transaction = ReactServerRenderingTransaction.getPooled(true); return transaction.perform(function() { var componentInstance = instantiateReactComponent(element, null); return componentInstance.mountComponent(id, transaction, emptyObject); }, null); } finally { ReactServerRenderingTransaction.release(transaction); } }
extractIfFragment: function(fragment) { if (__DEV__) { if (canWarnForReactFragment) { // If it is the opaque type, return the keyed object. if (fragment[fragmentKey]) { return fragment[fragmentKey]; } // Otherwise, check each property if it has an element, if it does // it is probably meant as a fragment, so we can warn early. Defer, // the warning to extract. for (var key in fragment) { if (fragment.hasOwnProperty(key) && ReactElement.isValidElement(fragment[key])) { // This looks like a fragment object, we should provide an // early warning. return ReactFragment.extract(fragment); } } } } return fragment; },
create: function(object) { if (__DEV__) { if (typeof object !== 'object' || !object || Array.isArray(object)) { warning( false, 'React.addons.createFragment only accepts a single object. Got: %s', object ); return object; } if (ReactElement.isValidElement(object)) { warning( false, 'React.addons.createFragment does not accept a ReactElement ' + 'without a wrapper object.' ); return object; } if (canWarnForReactFragment) { var proxy = {}; Object.defineProperty(proxy, fragmentKey, { enumerable: false, value: object, }); Object.defineProperty(proxy, didWarnKey, { writable: true, enumerable: false, value: false, }); for (var key in object) { proxyPropertyAccessWithWarning(proxy, key); } Object.preventExtensions(proxy); return proxy; } } return object; },
function() { var renderedComponent; var previousContext = ReactContext.current; ReactContext.current = this._processChildContext( this._currentElement._context ); ReactCurrentOwner.current = this; try { renderedComponent = this.render(); if (__DEV__) { // We allow auto-mocks to proceed as if they're returning null. if (typeof renderedComponent === 'undefined' && this.render._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. renderedComponent = null; } } if (renderedComponent === null || renderedComponent === false) { renderedComponent = ReactEmptyComponent.getEmptyComponent(); ReactEmptyComponent.registerNullComponentID(this._rootNodeID); } else { ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID); } } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null; } invariant( ReactElement.isValidElement(renderedComponent), '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.constructor.displayName || 'ReactCompositeComponent' ); return renderedComponent; }