mountComponent: function(
    transaction,
    nativeParent,
    nativeContainerInfo,
    context
  ) {
    this._context = context;
    this._mountOrder = nextMountID++;
    this._nativeParent = nativeParent;
    this._nativeContainerInfo = nativeContainerInfo;

    var publicProps = this._processProps(this._currentElement.props);
    var publicContext = this._processContext(context);

    var Component = this._currentElement.type;

    // Initialize the public class
    var inst;
    var renderedElement;

    if (Component.prototype && Component.prototype.isReactComponent) {
      if (__DEV__) {
        ReactCurrentOwner.current = this;
        try {
          inst = new Component(publicProps, publicContext, ReactUpdateQueue);
        } finally {
          ReactCurrentOwner.current = null;
        }
      } else {
        inst = new Component(publicProps, publicContext, ReactUpdateQueue);
      }
    } else {
      if (__DEV__) {
        ReactCurrentOwner.current = this;
        try {
          inst = Component(publicProps, publicContext, ReactUpdateQueue);
        } finally {
          ReactCurrentOwner.current = null;
        }
      } else {
        inst = Component(publicProps, publicContext, ReactUpdateQueue);
      }
      if (inst == null || inst.render == null) {
        renderedElement = inst;
        warnIfInvalidElement(Component, renderedElement);
        invariant(
          inst === null ||
          inst === false ||
          ReactElement.isValidElement(inst),
          '%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'
        );
        inst = new StatelessComponent(Component);
      }
    }

    if (__DEV__) {
      // This will throw later in _renderValidatedComponent, but add an early
      // warning now to help debugging
      if (inst.render == null) {
        warning(
          false,
          '%s(...): No `render` method found on the returned component ' +
          'instance: you may have forgotten to define `render`.',
          Component.displayName || Component.name || 'Component'
        );
      }

      var propsMutated = inst.props !== publicProps;
      var componentName =
        Component.displayName || Component.name || 'Component';

      warning(
        inst.props === undefined || !propsMutated,
        '%s(...): When calling super() in `%s`, make sure to pass ' +
        'up the same props that your component\'s constructor was passed.',
        componentName, componentName
      );
    }

    // These should be set up in the constructor, but as a convenience for
    // simpler class abstractions, we set them up after the fact.
    inst.props = publicProps;
    inst.context = publicContext;
    inst.refs = emptyObject;
    inst.updater = ReactUpdateQueue;

    this._instance = inst;

    // Store a reference from the instance back to the internal representation
    ReactInstanceMap.set(inst, this);

    if (__DEV__) {
      // Since plain JS classes are defined without any special initialization
      // logic, we can not catch common errors early. Therefore, we have to
      // catch them here, at initialization time, instead.
      warning(
        !inst.getInitialState ||
        inst.getInitialState.isReactClassApproved,
        'getInitialState was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Did you mean to define a state property instead?',
        this.getName() || 'a component'
      );
      warning(
        !inst.getDefaultProps ||
        inst.getDefaultProps.isReactClassApproved,
        'getDefaultProps was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Use a static property to define defaultProps instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.propTypes,
        'propTypes was defined as an instance property on %s. Use a static ' +
        'property to define propTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.contextTypes,
        'contextTypes was defined as an instance property on %s. Use a ' +
        'static property to define contextTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        typeof inst.componentShouldUpdate !== 'function',
        '%s has a method called ' +
        'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
        'The name is phrased as a question because the function is ' +
        'expected to return a value.',
        (this.getName() || 'A component')
      );
      warning(
        typeof inst.componentDidUnmount !== 'function',
        '%s has a method called ' +
        'componentDidUnmount(). But there is no such lifecycle method. ' +
        'Did you mean componentWillUnmount()?',
        this.getName() || 'A component'
      );
      warning(
        typeof inst.componentWillRecieveProps !== 'function',
        '%s has a method called ' +
        'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
        (this.getName() || 'A component')
      );
    }

    var initialState = inst.state;
    if (initialState === undefined) {
      inst.state = initialState = null;
    }
    invariant(
      typeof initialState === 'object' && !Array.isArray(initialState),
      '%s.state: must be set to an object or null',
      this.getName() || 'ReactCompositeComponent'
    );

    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;

    var markup;
    if (inst.unstable_handleError) {
      markup = this.performInitialMountWithErrorHandling(
        renderedElement,
        nativeParent,
        nativeContainerInfo,
        transaction,
        context
      );
    } else {
      markup = this.performInitialMount(renderedElement, nativeParent, nativeContainerInfo, transaction, context);
    }

    if (inst.componentDidMount) {
      transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
    }

    return markup;
  },
Example #2
0
   *   (i.e. #F0F & #FFF). Note that these cases rarely occur.
   *
   * Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
   */
  luminance(color) {
    color = this._decomposeColor(color);

    if (color.type.indexOf('rgb') > -1) {
      const rgb = color.values.map((val) => {
        val /= 255; // normalized
        return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);
      });

      return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
    } else {
      warning(false, `Calculating the relative luminance is not available
        for HSL and HSLA.`);

      return -1;
    }
  },

  /**
   * @params:
   * additionalValue = An extra value that has been calculated but not included
   *                   with the original color object, such as an alpha value.
   */
  _convertColorToString(color, additonalValue) {
    let str = `${color.type}(${
      parseInt(color.values[0])}, ${
      parseInt(color.values[1])}, ${
      parseInt(color.values[2])}`;
Example #3
0
/**
 * This function ensures that `style` supports both ltr and rtl directions by
 * checking `styleConstants` in `muiTheme` and replacing attribute keys if
 * necessary.
 */
function ensureDirection(muiTheme, style) {
  if (process.env.NODE_ENV !== 'production') {
    warning(!style.didFlip, `You're calling ensureDirection() on the same style
      object twice.`);

    style = mergeStyles({
      didFlip: 'true',
    }, style);
  }

  // Left to right is the default. No need to flip anything.
  if (!muiTheme || !muiTheme.isRtl) return style;

  const flippedAttributes = {
    // Keys and their replacements.
    right: 'left',
    left: 'right',
    marginRight: 'marginLeft',
    marginLeft: 'marginRight',
    paddingRight: 'paddingLeft',
    paddingLeft: 'paddingRight',
    borderRight: 'borderLeft',
    borderLeft: 'borderRight',
  };

  let newStyle = {};

  Object.keys(style).forEach(function(attribute) {
    let value = style[attribute];
    let key = attribute;

    if (flippedAttributes.hasOwnProperty(attribute)) {
      key = flippedAttributes[attribute];
    }

    switch (attribute) {
      case 'float':
      case 'textAlign':
        if (value === 'right') {
          value = 'left';
        } else if (value === 'left') {
          value = 'right';
        }
        break;

      case 'direction':
        if (value === 'ltr') {
          value = 'rtl';
        } else if (value === 'rtl') {
          value = 'ltr';
        }
        break;

      case 'transform':
        let matches;
        if ((matches = value.match(reTranslate))) {
          value = value.replace(matches[0], matches[1] + (-parseFloat(matches[4])) );
        }
        if ((matches = value.match(reSkew))) {
          value = value.replace(matches[0], matches[1] + (-parseFloat(matches[4])) + matches[5] +
            matches[6] ? ',' + (-parseFloat(matches[7])) + matches[8] : ''
          );
        }
        break;

      case 'transformOrigin':
        if (value.indexOf('right') > -1) {
          value = value.replace('right', 'left');
        } else if (value.indexOf('left') > -1) {
          value = value.replace('left', 'right');
        }
        break;
    }

    newStyle[key] = value;
  });

  return newStyle;
}
Example #4
0
      fragmentNames.forEach(fragmentName => {
        const propValue = props[fragmentName];
        warning(
          propValue !== undefined,
          'RelayContainer: Expected prop `%s` to be supplied to `%s`, but ' +
            'got `undefined`. Pass an explicit `null` if this is intentional.',
          fragmentName,
          componentName,
        );
        if (propValue == null) {
          fragmentPointers[fragmentName] = null;
          return;
        }
        // handle invalid prop values using a warning at first.
        if (typeof propValue !== 'object') {
          warning(
            false,
            'RelayContainer: Expected prop `%s` supplied to `%s` to be an ' +
              'object, got `%s`.',
            fragmentName,
            componentName,
            propValue,
          );
          fragmentPointers[fragmentName] = null;
          return;
        }
        const fragment = getFragment(fragmentName, context.route, variables);
        let dataIDOrIDs;

        if (fragment.isPlural()) {
          // Plural fragments require the prop value to be an array of fragment
          // pointers, which are merged into a single fragment pointer to pass
          // to the query resolver `resolve`.
          invariant(
            Array.isArray(propValue),
            'RelayContainer: Invalid prop `%s` supplied to `%s`, expected an ' +
              'array of records because the corresponding fragment has ' +
              '`@relay(plural: true)`.',
            fragmentName,
            componentName,
          );
          if (!propValue.length) {
            // Nothing to observe: pass the empty array through
            fragmentPointers[fragmentName] = null;
            return;
          }
          let dataIDs = null;
          propValue.forEach((item, ii) => {
            if (typeof item === 'object' && item != null) {
              if (RelayFragmentPointer.hasConcreteFragment(item, fragment)) {
                const dataID = RelayRecord.getDataIDForObject(item);
                if (dataID) {
                  dataIDs = dataIDs || [];
                  dataIDs.push(dataID);
                }
              }
              if (__DEV__) {
                if (
                  !context.route.useMockData &&
                  !context.useFakeData &&
                  !this._didShowFakeDataWarning
                ) {
                  const isValid = validateFragmentProp(
                    componentName,
                    fragmentName,
                    fragment,
                    item,
                    prevVariables,
                  );
                  this._didShowFakeDataWarning = !isValid;
                }
              }
            }
          });
          if (dataIDs) {
            invariant(
              dataIDs.length === propValue.length,
              'RelayContainer: Invalid prop `%s` supplied to `%s`. Some ' +
                'array items contain data fetched by Relay and some items ' +
                'contain null/mock data.',
              fragmentName,
              componentName,
            );
          }
          dataIDOrIDs = dataIDs;
        } else {
          invariant(
            !Array.isArray(propValue),
            'RelayContainer: Invalid prop `%s` supplied to `%s`, expected a ' +
              'single record because the corresponding fragment is not plural ' +
              '(i.e. does not have `@relay(plural: true)`).',
            fragmentName,
            componentName,
          );
          if (RelayFragmentPointer.hasConcreteFragment(propValue, fragment)) {
            dataIDOrIDs = RelayRecord.getDataIDForObject(propValue);
          }
          if (__DEV__) {
            if (
              !context.route.useMockData &&
              !context.useFakeData &&
              !this._didShowFakeDataWarning
            ) {
              const isValid = validateFragmentProp(
                componentName,
                fragmentName,
                fragment,
                propValue,
                prevVariables,
              );
              this._didShowFakeDataWarning = !isValid;
            }
          }
        }
        fragmentPointers[fragmentName] = dataIDOrIDs
          ? {fragment, dataIDs: dataIDOrIDs}
          : null;
      });
Example #5
0
ReactElement.cloneElement = function(element, config, children) {
  var propName;

  // Original props are copied
  var props = Object.assign({}, element.props);

  // Reserved names are extracted
  var key = element.key;
  var ref = element.ref;
  // Self is preserved since the owner is preserved.
  var self = element._self;
  // Source is preserved since cloneElement is unlikely to be targeted by a
  // transpiler, and the original source is probably a better indicator of the
  // true owner.
  var source = element._source;

  // Owner will be preserved, unless ref is overridden
  var owner = element._owner;

  if (config != null) {
    if (__DEV__) {
      warning(
        /* eslint-disable no-proto */
        config.__proto__ == null || config.__proto__ === Object.prototype,
        /* eslint-enable no-proto */
        'React.cloneElement(...): Expected props argument to be a plain object. ' +
        'Properties defined in its prototype chain will be ignored.'
      );
    }
    if (config.ref !== undefined) {
      // Silently steal the ref from the parent.
      ref = config.ref;
      owner = ReactCurrentOwner.current;
    }
    if (config.key !== undefined) {
      key = '' + config.key;
    }
    // Remaining properties override existing props
    var defaultProps;
    if (element.type && element.type.defaultProps) {
      defaultProps = element.type.defaultProps;
    }
    for (propName in config) {
      if (config.hasOwnProperty(propName) &&
          !RESERVED_PROPS.hasOwnProperty(propName)) {
        if (config[propName] === undefined && defaultProps !== undefined) {
          // Resolve default props
          props[propName] = defaultProps[propName];
        } else {
          props[propName] = config[propName];
        }
      }
    }
  }

  // Children can be more than one argument, and those are transferred onto
  // the newly allocated props object.
  var childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  return ReactElement(
    element.type,
    key,
    ref,
    self,
    source,
    owner,
    props
  );
};
Example #6
0
  _mountImageIntoNode: function(
    markup,
    container,
    instance,
    shouldReuseMarkup,
    transaction
  ) {
    invariant(
      isValidContainer(container),
      'mountComponentIntoNode(...): Target container is not valid.'
    );

    if (shouldReuseMarkup) {
      var rootElement = getReactRootElementInContainer(container);
      if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
        ReactDOMComponentTree.precacheNode(instance, rootElement);
        return;
      } else {
        var checksum = rootElement.getAttribute(
          ReactMarkupChecksum.CHECKSUM_ATTR_NAME
        );
        rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);

        var rootMarkup = rootElement.outerHTML;
        rootElement.setAttribute(
          ReactMarkupChecksum.CHECKSUM_ATTR_NAME,
          checksum
        );

        var normalizedMarkup = markup;
        if (__DEV__) {
          // because rootMarkup is retrieved from the DOM, various normalizations
          // will have occurred which will not be present in `markup`. Here,
          // insert markup into a <div> or <iframe> depending on the container
          // type to perform the same normalizations before comparing.
          var normalizer;
          if (container.nodeType === ELEMENT_NODE_TYPE) {
            normalizer = document.createElement('div');
            normalizer.innerHTML = markup;
            normalizedMarkup = normalizer.innerHTML;
          } else {
            normalizer = document.createElement('iframe');
            document.body.appendChild(normalizer);
            normalizer.contentDocument.write(markup);
            normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML;
            document.body.removeChild(normalizer);
          }
        }

        var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup);
        var difference = ' (client) ' +
          normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) +
          '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);

        invariant(
          container.nodeType !== DOC_NODE_TYPE,
          'You\'re trying to render a component to the document using ' +
          'server rendering but the checksum was invalid. This usually ' +
          'means you rendered a different component type or props on ' +
          'the client from the one on the server, or your render() ' +
          'methods are impure. React cannot handle this case due to ' +
          'cross-browser quirks by rendering at the document root. You ' +
          'should look for environment dependent code in your components ' +
          'and ensure the props are the same client and server side:\n%s',
          difference
        );

        if (__DEV__) {
          warning(
            false,
            'React attempted to reuse markup in a container but the ' +
            'checksum was invalid. This generally means that you are ' +
            'using server rendering and the markup generated on the ' +
            'server was not what the client was expecting. React injected ' +
            'new markup to compensate which works but you have lost many ' +
            'of the benefits of server rendering. Instead, figure out ' +
            'why the markup being generated is different on the client ' +
            'or server:\n%s',
            difference
          );
        }
      }
    }

    invariant(
      container.nodeType !== DOC_NODE_TYPE,
      'You\'re trying to render a component to the document but ' +
        'you didn\'t use server rendering. We can\'t do this ' +
        'without using server rendering due to cross-browser quirks. ' +
        'See ReactDOMServer.renderToString() for server rendering.'
    );

    if (transaction.useCreateElement) {
      while (container.lastChild) {
        container.removeChild(container.lastChild);
      }
      DOMLazyTree.insertTreeBefore(container, markup, null);
    } else {
      setInnerHTML(container, markup);
      ReactDOMComponentTree.precacheNode(instance, container.firstChild);
    }

    if (__DEV__) {
      var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild);
      if (hostNode._debugID !== 0) {
        ReactInstrumentation.debugTool.onHostOperation({
          instanceID: hostNode._debugID,
          type: 'mount',
          payload: markup.toString(),
        });
      }
    }
  },
export function* getRelatedEntities(
	entity,
	relationModelName,
	calculatedFields = []
) {
	if ( ! isModelEntity( entity ) ) {
		throw new InvalidModelEntity( '', entity );
	}
	// if entity is new then there won't be any relations for it on the server
	// yet, so let's just return early.
	if ( entity.isNew ) {
		return DEFAULT_EMPTY_ARRAY;
	}
	const modelName = entity.modelName.toLowerCase();
	const pluralRelationName = pluralModelName( relationModelName );
	const relationResourceProperty = pluralRelationName + 'Resource';
	const relationEndpoint = entity[ relationResourceProperty ] ?
		stripBaseRouteFromUrl(
			entity[ relationResourceProperty ].resourceLink
		) :
		'';
	if ( relationEndpoint === '' ) {
		warning(
			false,
			sprintf(
				'There is no relation resource for the given model (%s) and requested relation (%s)',
				modelName,
				pluralRelationName
			)
		);
		return DEFAULT_EMPTY_ARRAY;
	}
	yield dispatch(
		SCHEMA_REDUCER_KEY,
		'receiveRelationEndpointForModelEntity',
		modelName,
		entity.id,
		pluralRelationName,
		relationEndpoint
	);
	yield dispatch(
		'core/data',
		'finishResolution',
		SCHEMA_REDUCER_KEY,
		'receiveRelationEndpointForModelEntity',
		[ modelName, entity.id, pluralRelationName, relationEndpoint ]
	);

	// add calculatedFields to endpoint?
	const path = appendCalculatedFieldsToPath(
		relationEndpoint,
		calculatedFields
	);

	let relationEntities = yield fetch( { path } );

	relationEntities = ! isEmpty( relationEntities ) ?
		relationEntities :
		DEFAULT_EMPTY_ARRAY;
	relationEntities = ! isArray( relationEntities ) ?
		[ relationEntities ] :
		relationEntities;

	if ( ! relationEntities.length ) {
		return relationEntities;
	}

	const singularRelationName = singularModelName( relationModelName );
	const factory = yield resolveSelect(
		SCHEMA_REDUCER_KEY,
		'getFactoryForModel',
		singularRelationName
	);
	if ( ! isModelEntityFactoryOfModel(
		factory,
		singularRelationName
	) ) {
		return DEFAULT_EMPTY_ARRAY;
	}

	let fullEntities = keyEntitiesByPrimaryKeyValue(
		singularRelationName,
		relationEntities
	);
	fullEntities = createAndKeyEntitiesByPrimaryKeyValue(
		factory,
		fullEntities,
	);
	const entityIds = Array.from( fullEntities.keys() );

	// are there already entities for the ids in the store? If so...we use
	// those.
	const existingEntities = yield select(
		CORE_REDUCER_KEY,
		'getEntitiesByIds',
		singularRelationName,
		entityIds
	);

	if ( ! isEmpty( existingEntities ) ) {
		fullEntities = keepExistingEntitiesInObject(
			existingEntities.reduce(
				( entitiesObject, entityObj ) => {
					entitiesObject[ entityObj.id ] = entity;
					return entitiesObject;
				},
				{}
			),
			fullEntities,
		);
	}

	// if fullEntities is not a map, then we need to make it a map
	const entityArray = fullEntities instanceof Map ?
		Array.from( fullEntities.values() ) :
		fullEntities;

	yield receiveEntityRecords(
		singularRelationName,
		entityArray
	);
	yield receiveRelatedEntities(
		modelName,
		entity.id,
		pluralRelationName,
		entityIds,
	);
	yield resolveGetRelatedEntities(
		entity,
		fullEntities,
		entityIds,
	);
	yield resolveGetEntityByIdForIds(
		singularRelationName,
		entityIds
	);
	return entityArray;
}
 componentWillReceiveProps(nextProps) {
   warning(
     nextProps.scrollKey === this.props.scrollKey,
     '<ScrollContainer> does not support changing scrollKey.',
   );
 }
Example #9
0
/**
 * Writes the node data for the given field to the store and prepends/appends
 * the node to the given connection.
 */
function addRangeNode(
  writer: RelayQueryWriter,
  operation: RelayQuery.Operation,
  config: OperationConfig,
  connectionID: DataID,
  nodeID: DataID,
  edgeData: any,
) {
  const store = writer.getRecordStore();
  const recordWriter = writer.getRecordWriter();
  const filterCalls = store.getRangeFilterCalls(connectionID);
  const rangeBehavior = filterCalls
    ? getRangeBehavior(config.rangeBehaviors, filterCalls)
    : null;

  // no range behavior specified for this combination of filter calls
  if (!rangeBehavior) {
    warning(
      rangeBehavior,
      'Using `null` as a rangeBehavior value is deprecated. Use `ignore` to avoid ' +
        'refetching a range.',
    );
    return;
  }

  if (rangeBehavior === IGNORE) {
    return;
  }

  const edgeID = generateClientEdgeID(connectionID, nodeID);
  let path = store.getPathToRecord(connectionID);
  invariant(
    path,
    'writeRelayUpdatePayload(): Expected a path for connection record, `%s`.',
    connectionID,
  );
  const edgesField = getEdgesField();
  path = RelayQueryPath.getPath(path, edgesField, edgeID);

  // create the edge record
  writer.createRecordIfMissing(edgesField, edgeID, path, edgeData);

  // write data for all `edges` fields
  // TODO #7167718: more efficient mutation/subscription writes
  let hasEdgeField = false;
  const handleNode = node => {
    node.getChildren().forEach(child => {
      if (child instanceof RelayQuery.Fragment) {
        handleNode(child);
      } else if (
        child instanceof RelayQuery.Field &&
        child.getSchemaName() === config.edgeName
      ) {
        hasEdgeField = true;
        if (path) {
          writer.writePayload(child, edgeID, edgeData, path);
        }
      }
    });
  };
  handleNode(operation);

  invariant(
    hasEdgeField,
    'writeRelayUpdatePayload(): Expected mutation query to include the ' +
      'relevant edge field, `%s`.',
    config.edgeName,
  );

  // append/prepend the item to the range.
  if (
    rangeBehavior === APPEND ||
    rangeBehavior === IGNORE ||
    rangeBehavior === PREPEND ||
    rangeBehavior === REFETCH ||
    rangeBehavior === REMOVE
  ) {
    recordWriter.applyRangeUpdate(
      connectionID,
      edgeID,
      (rangeBehavior: $FlowFixMe),
    );
    writer.recordUpdate(connectionID);
  } else {
    console.error(
      'writeRelayUpdatePayload(): invalid range operation `%s`, valid ' +
        'options are `%s`, `%s`, `%s`, `%s`, or `%s`.',
      rangeBehavior,
      APPEND,
      PREPEND,
      IGNORE,
      REMOVE,
      REFETCH,
    );
  }
}
/**
 * @public
 *
 * A default runtime handler for connection fields that appends newly fetched
 * edges onto the end of a connection, regardless of the arguments used to fetch
 * those edges.
 */
function update(store: RecordSourceProxy, payload: HandleFieldPayload): void {
  const record = store.get(payload.dataID);
  if (!record) {
    return;
  }

  const {
    EDGES,
    END_CURSOR,
    HAS_NEXT_PAGE,
    HAS_PREV_PAGE,
    PAGE_INFO,
    PAGE_INFO_TYPE,
    START_CURSOR,
  } = RelayConnectionInterface.get();

  const serverConnection = record.getLinkedRecord(payload.fieldKey);
  const serverPageInfo =
    serverConnection && serverConnection.getLinkedRecord(PAGE_INFO);
  if (!serverConnection) {
    record.setValue(null, payload.handleKey);
    return;
  }
  const clientConnection = record.getLinkedRecord(payload.handleKey);
  let clientPageInfo =
    clientConnection && clientConnection.getLinkedRecord(PAGE_INFO);
  if (!clientConnection) {
    // Initial fetch with data: copy fields from the server record
    const connection = store.create(
      generateRelayClientID(record.getDataID(), payload.handleKey),
      serverConnection.getType(),
    );
    connection.setValue(0, NEXT_EDGE_INDEX);
    connection.copyFieldsFrom(serverConnection);
    let serverEdges = serverConnection.getLinkedRecords(EDGES);
    if (serverEdges) {
      serverEdges = serverEdges.map(edge =>
        buildConnectionEdge(store, connection, edge),
      );
      connection.setLinkedRecords(serverEdges, EDGES);
    }
    record.setLinkedRecord(connection, payload.handleKey);

    clientPageInfo = store.create(
      generateRelayClientID(connection.getDataID(), PAGE_INFO),
      PAGE_INFO_TYPE,
    );
    clientPageInfo.setValue(false, HAS_NEXT_PAGE);
    clientPageInfo.setValue(false, HAS_PREV_PAGE);
    clientPageInfo.setValue(null, END_CURSOR);
    clientPageInfo.setValue(null, START_CURSOR);
    if (serverPageInfo) {
      clientPageInfo.copyFieldsFrom(serverPageInfo);
    }
    connection.setLinkedRecord(clientPageInfo, PAGE_INFO);
  } else {
    const connection = clientConnection;
    // Subsequent fetches:
    // - updated fields on the connection
    // - merge prev/next edges, de-duplicating by node id
    // - synthesize page info fields
    let serverEdges = serverConnection.getLinkedRecords(EDGES);
    if (serverEdges) {
      serverEdges = serverEdges.map(edge =>
        buildConnectionEdge(store, connection, edge),
      );
    }
    const prevEdges = connection.getLinkedRecords(EDGES);
    const prevPageInfo = connection.getLinkedRecord(PAGE_INFO);
    connection.copyFieldsFrom(serverConnection);
    // Reset EDGES and PAGE_INFO fields
    if (prevEdges) {
      connection.setLinkedRecords(prevEdges, EDGES);
    }
    if (prevPageInfo) {
      connection.setLinkedRecord(prevPageInfo, PAGE_INFO);
    }

    let nextEdges = [];
    const args = payload.args;
    if (prevEdges && serverEdges) {
      if (args.after != null) {
        // Forward pagination from the end of the connection: append edges
        if (
          clientPageInfo &&
          args.after === clientPageInfo.getValue(END_CURSOR)
        ) {
          const nodeIDs = new Set();
          mergeEdges(prevEdges, nextEdges, nodeIDs);
          mergeEdges(serverEdges, nextEdges, nodeIDs);
        } else {
          warning(
            false,
            'RelayConnectionHandler: Unexpected after cursor `%s`, edges must ' +
              'be fetched from the end of the list (`%s`).',
            args.after,
            clientPageInfo && clientPageInfo.getValue(END_CURSOR),
          );
          return;
        }
      } else if (args.before != null) {
        // Backward pagination from the start of the connection: prepend edges
        if (
          clientPageInfo &&
          args.before === clientPageInfo.getValue(START_CURSOR)
        ) {
          const nodeIDs = new Set();
          mergeEdges(serverEdges, nextEdges, nodeIDs);
          mergeEdges(prevEdges, nextEdges, nodeIDs);
        } else {
          warning(
            false,
            'RelayConnectionHandler: Unexpected before cursor `%s`, edges must ' +
              'be fetched from the beginning of the list (`%s`).',
            args.before,
            clientPageInfo && clientPageInfo.getValue(START_CURSOR),
          );
          return;
        }
      } else {
        // The connection was refetched from the beginning/end: replace edges
        nextEdges = serverEdges;
      }
    } else if (serverEdges) {
      nextEdges = serverEdges;
    } else {
      nextEdges = prevEdges;
    }
    // Update edges only if they were updated, the null check is
    // for Flow (prevEdges could be null).
    if (nextEdges != null && nextEdges !== prevEdges) {
      connection.setLinkedRecords(nextEdges, EDGES);
    }
    // Page info should be updated even if no new edge were returned.
    if (clientPageInfo && serverPageInfo) {
      if (args.before != null || (args.after == null && args.last)) {
        clientPageInfo.setValue(
          !!serverPageInfo.getValue(HAS_PREV_PAGE),
          HAS_PREV_PAGE,
        );
        const startCursor = serverPageInfo.getValue(START_CURSOR);
        if (typeof startCursor === 'string') {
          clientPageInfo.setValue(startCursor, START_CURSOR);
        }
      } else if (args.after != null || (args.before == null && args.first)) {
        clientPageInfo.setValue(
          !!serverPageInfo.getValue(HAS_NEXT_PAGE),
          HAS_NEXT_PAGE,
        );
        const endCursor = serverPageInfo.getValue(END_CURSOR);
        if (typeof endCursor === 'string') {
          clientPageInfo.setValue(endCursor, END_CURSOR);
        }
      }
    }
  }
}
Example #11
0
  render() {
    const _props = this.props,
          {
      action,
      centered,
      children: childrenProp,
      classes,
      className: classNameProp,
      fullWidth,
      indicatorColor,
      onChange,
      scrollable,
      scrollButtons,
      TabScrollButton: TabScrollButtonProp,
      textColor,
      theme,
      value
    } = _props,
          other = _objectWithoutProperties(_props, ['action', 'centered', 'children', 'classes', 'className', 'fullWidth', 'indicatorColor', 'onChange', 'scrollable', 'scrollButtons', 'TabScrollButton', 'textColor', 'theme', 'value']);

    process.env.NODE_ENV !== "production" ? warning(!centered || !scrollable, 'Material-UI: you can not use the `centered={true}` and `scrollable={true}` properties ' + 'at the same time on a `Tabs` component.') : void 0;

    const className = classNames(classes.root, classNameProp);
    const scrollerClassName = classNames(classes.scroller, {
      [classes.fixed]: !scrollable,
      [classes.scrollable]: scrollable
    });
    const flexContainerClassName = classNames(classes.flexContainer, {
      [classes.centered]: centered && !scrollable
    });

    const indicator = React.createElement(TabIndicator, {
      style: this.state.indicatorStyle,
      className: classes.indicator,
      color: indicatorColor
    });

    this.valueToIndex = {};
    let childIndex = 0;
    const children = React.Children.map(childrenProp, child => {
      if (!React.isValidElement(child)) {
        return null;
      }

      const childValue = child.props.value === undefined ? childIndex : child.props.value;
      this.valueToIndex[childValue] = childIndex;
      const selected = childValue === value;

      childIndex += 1;
      return React.cloneElement(child, {
        fullWidth,
        indicator: selected && !this.state.mounted && indicator,
        selected,
        onChange,
        textColor,
        value: childValue
      });
    });

    const conditionalElements = this.getConditionalElements();

    return React.createElement(
      'div',
      _extends({ className: className }, other),
      React.createElement(EventListener, { target: 'window', onResize: this.handleResize }),
      conditionalElements.scrollbarSizeListener,
      React.createElement(
        'div',
        { className: classes.flexContainer },
        conditionalElements.scrollButtonLeft,
        React.createElement(
          'div',
          {
            className: scrollerClassName,
            style: this.state.scrollerStyle,
            ref: node => {
              this.tabs = node;
            },
            role: 'tablist',
            onScroll: this.handleTabsScroll
          },
          React.createElement(
            'div',
            { className: flexContainerClassName },
            children
          ),
          this.state.mounted && indicator
        ),
        conditionalElements.scrollButtonRight
      )
    );
  }
Example #12
0
/**
 * @param {object} component
 * @param {?object} props
 */
function assertValidProps(component, props) {
  if (!props) {
    return;
  }
  // Note the use of `==` which checks for null or undefined.
  if (voidElementTags[component._tag]) {
    invariant(
      props.children == null && props.dangerouslySetInnerHTML == null,
      '%s is a void element tag and must neither have `children` nor ' +
      'use `dangerouslySetInnerHTML`.%s',
      component._tag,
      component._currentElement._owner ?
        ' Check the render method of ' +
        component._currentElement._owner.getName() + '.' :
        ''
    );
  }
  if (props.dangerouslySetInnerHTML != null) {
    invariant(
      props.children == null,
      'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
    );
    invariant(
      typeof props.dangerouslySetInnerHTML === 'object' &&
      HTML in props.dangerouslySetInnerHTML,
      '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
      'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' +
      'for more information.'
    );
  }
  if (__DEV__) {
    warning(
      props.innerHTML == null,
      'Directly setting property `innerHTML` is not permitted. ' +
      'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
    );
    warning(
      props.suppressContentEditableWarning ||
      !props.contentEditable ||
      props.children == null,
      'A component is `contentEditable` and contains `children` managed by ' +
      'React. It is now your responsibility to guarantee that none of ' +
      'those nodes are unexpectedly modified or duplicated. This is ' +
      'probably not intentional.'
    );
    warning(
      props.onFocusIn == null &&
      props.onFocusOut == null,
      'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' +
      'All React events are normalized to bubble, so onFocusIn and onFocusOut ' +
      'are not needed/supported by React.'
    );
  }
  invariant(
    props.style == null || typeof props.style === 'object',
    'The `style` prop expects a mapping from style properties to values, ' +
    'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' +
    'using JSX.%s',
     getDeclarationErrorAddendum(component)
  );
}
 test: function() {
   warning("Not yet implemented for Android.");
 }
Example #14
0
      stringifyQuery
    })

    this._unlisten = this.history.listen((error, state) => {
      if (error) {
        this.handleError(error)
      } else {
        this.setState(state, this.props.onUpdate)
      }
    })
  },

  /* istanbul ignore next: sanity check */
  componentWillReceiveProps(nextProps) {
    warning(
      nextProps.history === this.props.history,
      'You cannot change <Router history>; it will be ignored'
    )

    warning(
      (nextProps.routes || nextProps.children) ===
        (this.props.routes || this.props.children),
      'You cannot change <Router routes>; it will be ignored'
    )
  },

  componentWillUnmount() {
    if (this._unlisten)
      this._unlisten()
  },

  render() {
Example #15
0
  _renderSubtreeIntoContainer: function(parentComponent, nextElement, container, callback) {
    ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render');
    invariant(
      React.isValidElement(nextElement),
      'ReactDOM.render(): Invalid component element.%s',
      (
        typeof nextElement === 'string' ?
          ' Instead of passing a string like \'div\', pass ' +
          'React.createElement(\'div\') or <div />.' :
        typeof nextElement === 'function' ?
          ' Instead of passing a class like Foo, pass ' +
          'React.createElement(Foo) or <Foo />.' :
        // Check if it quacks like an element
        nextElement != null && nextElement.props !== undefined ?
          ' This may be caused by unintentionally loading two independent ' +
          'copies of React.' :
          ''
      )
    );

    warning(
      !container || !container.tagName ||
      container.tagName.toUpperCase() !== 'BODY',
      'render(): Rendering components directly into document.body is ' +
      'discouraged, since its children are often manipulated by third-party ' +
      'scripts and browser extensions. This may lead to subtle ' +
      'reconciliation issues. Try rendering into a container element created ' +
      'for your app.'
    );

    var nextWrappedElement = React.createElement(
      TopLevelWrapper,
      { child: nextElement }
    );

    var nextContext;
    if (parentComponent) {
      var parentInst = ReactInstanceMap.get(parentComponent);
      nextContext = parentInst._processChildContext(parentInst._context);
    } else {
      nextContext = emptyObject;
    }

    var prevComponent = getTopLevelWrapperInContainer(container);

    if (prevComponent) {
      var prevWrappedElement = prevComponent._currentElement;
      var prevElement = prevWrappedElement.props.child;
      if (shouldUpdateReactComponent(prevElement, nextElement)) {
        var publicInst = prevComponent._renderedComponent.getPublicInstance();
        var updatedCallback = callback && function() {
          callback.call(publicInst);
        };
        ReactMount._updateRootComponent(
          prevComponent,
          nextWrappedElement,
          nextContext,
          container,
          updatedCallback
        );
        return publicInst;
      } else {
        ReactMount.unmountComponentAtNode(container);
      }
    }

    var reactRootElement = getReactRootElementInContainer(container);
    var containerHasReactMarkup =
      reactRootElement && !!internalGetID(reactRootElement);
    var containerHasNonRootReactChild = hasNonRootReactChild(container);

    if (__DEV__) {
      warning(
        !containerHasNonRootReactChild,
        'render(...): Replacing React-rendered children with a new root ' +
        'component. If you intended to update the children of this node, ' +
        'you should instead have the existing children update their state ' +
        'and render the new components instead of calling ReactDOM.render.'
      );

      if (!containerHasReactMarkup || reactRootElement.nextSibling) {
        var rootElementSibling = reactRootElement;
        while (rootElementSibling) {
          if (internalGetID(rootElementSibling)) {
            warning(
              false,
              'render(): Target node has markup rendered by React, but there ' +
              'are unrelated nodes as well. This is most commonly caused by ' +
              'white-space inserted around server-rendered markup.'
            );
            break;
          }
          rootElementSibling = rootElementSibling.nextSibling;
        }
      }
    }

    var shouldReuseMarkup =
      containerHasReactMarkup &&
      !prevComponent &&
      !containerHasNonRootReactChild;
    var component = ReactMount._renderNewRootComponent(
      nextWrappedElement,
      container,
      shouldReuseMarkup,
      nextContext,
      callback
    )._renderedComponent.getPublicInstance();
    return component;
  },
Example #16
0
/**
 * Handles the payload for a range edge deletion, which removes the edge from
 * a specified range but does not delete the node for that edge. The config
 * specifies the path within the payload that contains the connection ID.
 */
function handleRangeDelete(
  writer: RelayQueryWriter,
  payload: PayloadObject,
  config: OperationConfig,
): void {
  const store = writer.getRecordStore();

  let recordIDs = null;

  if (Array.isArray(config.deletedIDFieldName)) {
    recordIDs = getIDsFromPath(store, config.deletedIDFieldName, payload);
  } else {
    recordIDs = payload[config.deletedIDFieldName];

    // Coerce numbers to strings for backwards compatibility.
    if (typeof recordIDs === 'number') {
      warning(
        false,
        'writeRelayUpdatePayload(): Expected `%s` to be a string, got the ' +
          'number `%s`.',
        config.deletedIDFieldName,
        recordIDs,
      );
      recordIDs = '' + recordIDs;
    }

    invariant(
      recordIDs == null ||
        (!Array.isArray(recordIDs) || typeof recordIDs !== 'string'),
      'writeRelayUpdatePayload(): Expected `%s` to be an array/string, got `%s`.',
      config.deletedIDFieldName,
      JSON.stringify(recordIDs),
    );

    if (!Array.isArray(recordIDs)) {
      recordIDs = [recordIDs];
    }
  }

  invariant(
    recordIDs != null,
    'writeRelayUpdatePayload(): Missing ID(s) for deleted record at field `%s`.',
    config.deletedIDFieldName,
  );

  // Extract the id of the node with the connection that we are deleting from.
  const connectionName = config.pathToConnection.pop();
  const connectionParentIDs = getIDsFromPath(
    store,
    config.pathToConnection,
    payload,
  );
  // Restore pathToConnection to its original state
  config.pathToConnection.push(connectionName);
  if (!connectionParentIDs) {
    return;
  }
  const connectionParentID = connectionParentIDs[0];

  const connectionIDs = store.getConnectionIDsForField(
    connectionParentID,
    connectionName,
  );
  if (connectionIDs) {
    connectionIDs.forEach(connectionID => {
      if (recordIDs) {
        recordIDs.forEach(recordID => {
          deleteRangeEdge(writer, connectionID, recordID);
        });
      }
    });
  }
}
Example #17
0
  unmountComponentAtNode: function(container) {
    // Various parts of our code (such as ReactCompositeComponent's
    // _renderValidatedComponent) assume that calls to render aren't nested;
    // verify that that's the case. (Strictly speaking, unmounting won't cause a
    // render but we still don't expect to be in a render call here.)
    warning(
      ReactCurrentOwner.current == null,
      'unmountComponentAtNode(): Render methods should be a pure function ' +
      'of props and state; triggering nested component updates from render ' +
      'is not allowed. If necessary, trigger nested updates in ' +
      'componentDidUpdate. Check the render method of %s.',
      ReactCurrentOwner.current && ReactCurrentOwner.current.getName() ||
        'ReactCompositeComponent'
    );

    invariant(
      isValidContainer(container),
      'unmountComponentAtNode(...): Target container is not a DOM element.'
    );

    if (__DEV__) {
      warning(
        !nodeIsRenderedByOtherInstance(container),
        'unmountComponentAtNode(): The node you\'re attempting to unmount ' +
        'was rendered by another copy of React.'
      );
    }

    var prevComponent = getTopLevelWrapperInContainer(container);
    if (!prevComponent) {
      // Check if the node being unmounted was rendered by React, but isn't a
      // root node.
      var containerHasNonRootReactChild = hasNonRootReactChild(container);

      // Check if the container itself is a React root node.
      var isContainerReactRoot =
        container.nodeType === 1 && container.hasAttribute(ROOT_ATTR_NAME);

      if (__DEV__) {
        warning(
          !containerHasNonRootReactChild,
          'unmountComponentAtNode(): The node you\'re attempting to unmount ' +
          'was rendered by React and is not a top-level container. %s',
          (
            isContainerReactRoot ?
              'You may have accidentally passed in a React root node instead ' +
              'of its container.' :
              'Instead, have the parent component update its state and ' +
              'rerender in order to remove this component.'
          )
        );
      }

      return false;
    }
    delete instancesByReactRootID[prevComponent._instance.rootID];
    ReactUpdates.batchedUpdates(
      unmountComponentFromNode,
      prevComponent,
      container
    );
    return true;
  },
/**
 * Given a ReactNode, create an instance that will actually be mounted.
 *
 * @param {ReactNode} node
 * @return {object} A new instance of the element's constructor.
 * @protected
 */
function instantiateReactComponent(node) {
  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 = ReactNativeComponent.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);
    } else {
      instance = new ReactCompositeComponentWrapper();
    }
  } else if (typeof node === 'string' || typeof node === 'number') {
    instance = ReactNativeComponent.createInstanceForText(node);
  } else {
    invariant(
      false,
      'Encountered invalid React node of type %s',
      typeof node
    );
  }

  if (__DEV__) {
    warning(
      typeof instance.construct === 'function' &&
      typeof instance.mountComponent === 'function' &&
      typeof instance.receiveComponent === 'function' &&
      typeof instance.getNativeNode === 'function' &&
      typeof instance.unmountComponent === 'function',
      'Only React Components can be mounted.'
    );
  }

  // Sets up the instance. This can probably just move into the constructor now.
  instance.construct(node);

  // 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._isOwnerNecessary = false;
    instance._warnedAboutRefsInRender = false;
  }

  // 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;
}
Example #19
0
    forEachObject(fragments, (fragmentBuilder, fragmentName) => {
      const propValue = props[fragmentName];
      warning(
        propValue !== undefined,
        'RelayMutation: Expected data for fragment `%s` to be supplied to ' +
        '`%s` as a prop. Pass an explicit `null` if this is intentional.',
        fragmentName,
        this.constructor.name
      );

      if (propValue == null) {
        return;
      }
      if (typeof propValue !== 'object') {
        warning(
          false,
          'RelayMutation: Expected data for fragment `%s` supplied to `%s` ' +
          'to be an object.',
          fragmentName,
          this.constructor.name
        );
        return;
      }

      const fragment = RelayQuery.Fragment.create(
        buildMutationFragment(
          this.constructor.name,
          fragmentName,
          fragmentBuilder,
          initialVariables
        ),
        RelayMetaRoute.get(`$RelayMutation_${this.constructor.name}`),
        initialVariables
      );

      if (fragment.isPlural()) {
        invariant(
          Array.isArray(propValue),
          'RelayMutation: Invalid prop `%s` supplied to `%s`, expected an ' +
          'array of records because the corresponding fragment is plural.',
          fragmentName,
          this.constructor.name
        );
        const dataIDs = propValue.map((item, ii) => {
          invariant(
            typeof item === 'object' && item != null,
            'RelayMutation: Invalid prop `%s` supplied to `%s`, ' +
            'expected element at index %s to have query data.',
            fragmentName,
            this.constructor.name,
            ii
          );
          const dataID = RelayFragmentPointer.getDataID(item, fragment);
          invariant(
            dataID,
            'RelayMutation: Invalid prop `%s` supplied to `%s`, ' +
            'expected element at index %s to have query data.',
            fragmentName,
            this.constructor.name,
            ii
          );
          return dataID;
        });

        resolvedProps[fragmentName] = dataIDs.map(
          dataID => this._environment.read(fragment, dataID)
        );
      } else {
        invariant(
          !Array.isArray(propValue),
          'RelayMutation: Invalid prop `%s` supplied to `%s`, expected a ' +
          'single record because the corresponding fragment is not plural.',
          fragmentName,
          this.constructor.name
        );
        const dataID = RelayFragmentPointer.getDataID(propValue, fragment);
        if (dataID) {
          resolvedProps[fragmentName] = this._environment.read(
            fragment,
            dataID
          );
        } else {
          if (__DEV__) {
            if (!this._didShowFakeDataWarning) {
              this._didShowFakeDataWarning = true;
              warning(
                false,
                'RelayMutation: Expected prop `%s` supplied to `%s` to ' +
                'be data fetched by Relay. This is likely an error unless ' +
                'you are purposely passing in mock data that conforms to ' +
                'the shape of this mutation\'s fragment.',
                fragmentName,
                this.constructor.name
              );
            }
          }
        }
      }
    });
Example #20
0
  updateWrapper: function(inst) {
    var props = inst._currentElement.props;

    if (__DEV__) {
      warnIfValueIsNull(props);

      var initialValue = inst._wrapperState.initialChecked || inst._wrapperState.initialValue;
      var defaultValue = props.defaultChecked || props.defaultValue;
      var controlled = props.checked !== undefined || props.value !== undefined;
      var owner = inst._currentElement._owner;

      if (
        (initialValue || !inst._wrapperState.controlled) &&
        controlled && !didWarnUncontrolledToControlled
      ) {
        warning(
          false,
          '%s is changing a uncontrolled input of type %s to be controlled. ' +
          'Input elements should not switch from uncontrolled to controlled (or viceversa). ' +
          'Decide between using a controlled or uncontrolled input ' +
          'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
          owner && owner.getName() || 'A component',
          props.type
        );
        didWarnUncontrolledToControlled = true;
      }
      if (
        inst._wrapperState.controlled &&
        (defaultValue || !controlled) &&
        !didWarnControlledToUncontrolled
      ) {
        warning(
          false,
          '%s is changing a controlled input of type %s to be uncontrolled. ' +
          'Input elements should not switch from controlled to uncontrolled (or viceversa). ' +
          'Decide between using a controlled or uncontrolled input ' +
          'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
          owner && owner.getName() || 'A component',
          props.type
        );
        didWarnControlledToUncontrolled = true;
      }
    }

    // TODO: Shouldn't this be getChecked(props)?
    var checked = props.checked;
    if (checked != null) {
      DOMPropertyOperations.setValueForProperty(
        ReactDOMComponentTree.getNodeFromInstance(inst),
        'checked',
        checked || false
      );
    }

    var value = LinkedValueUtils.getValue(props);
    if (value != null) {
      // Cast `value` to a string to ensure the value is set correctly. While
      // browsers typically do this as necessary, jsdom doesn't.
      DOMPropertyOperations.setValueForProperty(
        ReactDOMComponentTree.getNodeFromInstance(inst),
        'value',
        '' + value
      );
    }
  },
Example #21
0
  createClass: function(spec) {
    var Constructor = function(props, context, updater) {
      // This constructor gets overridden by mocks. The argument is used
      // by mocks to assert on what gets mounted.

      if (__DEV__) {
        warning(
          this instanceof Constructor,
          'Something is calling a React component directly. Use a factory or ' +
          'JSX instead. See: https://fb.me/react-legacyfactory'
        );
      }

      // Wire up auto-binding
      if (this.__reactAutoBindPairs.length) {
        bindAutoBindMethods(this);
      }

      this.props = props;
      this.context = context;
      this.refs = emptyObject;
      this.updater = updater || ReactNoopUpdateQueue;

      this.state = null;

      // ReactClasses doesn't have constructors. Instead, they use the
      // getInitialState and componentWillMount methods for initialization.

      var initialState = this.getInitialState ? this.getInitialState() : null;
      if (__DEV__) {
        // We allow auto-mocks to proceed as if they're returning null.
        if (initialState === undefined &&
            this.getInitialState._isMockFunction) {
          // This is probably bad practice. Consider warning here and
          // deprecating this convenience.
          initialState = null;
        }
      }
      invariant(
        typeof initialState === 'object' && !Array.isArray(initialState),
        '%s.getInitialState(): must return an object or null',
        Constructor.displayName || 'ReactCompositeComponent'
      );

      this.state = initialState;
    };
    Constructor.prototype = new ReactClassComponent();
    Constructor.prototype.constructor = Constructor;
    Constructor.prototype.__reactAutoBindPairs = [];

    injectedMixins.forEach(
      mixSpecIntoComponent.bind(null, Constructor)
    );

    mixSpecIntoComponent(Constructor, spec);

    // Initialize the defaultProps property after all mixins have been merged.
    if (Constructor.getDefaultProps) {
      Constructor.defaultProps = Constructor.getDefaultProps();
    }

    if (__DEV__) {
      // This is a tag to indicate that the use of these method names is ok,
      // since it's used with createClass. If it's not, then it's likely a
      // mistake so we'll warn you to use the static property, property
      // initializer or constructor respectively.
      if (Constructor.getDefaultProps) {
        Constructor.getDefaultProps.isReactClassApproved = {};
      }
      if (Constructor.prototype.getInitialState) {
        Constructor.prototype.getInitialState.isReactClassApproved = {};
      }
    }

    invariant(
      Constructor.prototype.render,
      'createClass(...): Class specification must implement a `render` method.'
    );

    if (__DEV__) {
      warning(
        !Constructor.prototype.componentShouldUpdate,
        '%s has a method called ' +
        'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
        'The name is phrased as a question because the function is ' +
        'expected to return a value.',
        spec.displayName || 'A component'
      );
      warning(
        !Constructor.prototype.componentWillRecieveProps,
        '%s has a method called ' +
        'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
        spec.displayName || 'A component'
      );
    }

    // Reduce time spent doing lookups by setting these on the prototype.
    for (var methodName in ReactClassInterface) {
      if (!Constructor.prototype[methodName]) {
        Constructor.prototype[methodName] = null;
      }
    }

    return Constructor;
  },
Example #22
0
  mountWrapper: function(inst, props) {
    if (__DEV__) {
      LinkedValueUtils.checkPropTypes(
        'input',
        props,
        inst._currentElement._owner
      );

      var owner = inst._currentElement._owner;

      if (props.valueLink !== undefined && !didWarnValueLink) {
        warning(
          false,
          '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.'
        );
        didWarnValueLink = true;
      }
      if (props.checkedLink !== undefined && !didWarnCheckedLink) {
        warning(
          false,
          '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.'
        );
        didWarnCheckedLink = true;
      }
      if (
        props.checked !== undefined &&
        props.defaultChecked !== undefined &&
        !didWarnCheckedDefaultChecked
      ) {
        warning(
          false,
          '%s contains an input of type %s with both checked and defaultChecked props. ' +
          'Input elements must be either controlled or uncontrolled ' +
          '(specify either the checked prop, or the defaultChecked prop, but not ' +
          'both). Decide between using a controlled or uncontrolled input ' +
          'element and remove one of these props. More info: ' +
          'https://fb.me/react-controlled-components',
          owner && owner.getName() || 'A component',
          props.type
        );
        didWarnCheckedDefaultChecked = true;
      }
      if (
        props.value !== undefined &&
        props.defaultValue !== undefined &&
        !didWarnValueDefaultValue
      ) {
        warning(
          false,
          '%s contains an input of type %s with both value and defaultValue props. ' +
          'Input elements must be either controlled or uncontrolled ' +
          '(specify either the value prop, or the defaultValue prop, but not ' +
          'both). Decide between using a controlled or uncontrolled input ' +
          'element and remove one of these props. More info: ' +
          'https://fb.me/react-controlled-components',
          owner && owner.getName() || 'A component',
          props.type
        );
        didWarnValueDefaultValue = true;
      }
      warnIfValueIsNull(props);
    }

    var defaultValue = props.defaultValue;
    inst._wrapperState = {
      initialChecked: props.defaultChecked || false,
      initialValue: defaultValue != null ? defaultValue : null,
      listeners: null,
      onChange: _handleChange.bind(inst),
    };

    if (__DEV__) {
      inst._wrapperState.controlled = props.checked !== undefined || props.value !== undefined;
    }
  },
Example #23
0
ReactElement.createElement = function(type, config, children) {
  var propName;

  // Reserved names are extracted
  var props = {};

  var key = null;
  var ref = null;
  var self = null;
  var source = null;

  if (config != null) {
    if (__DEV__) {
      warning(
        /* eslint-disable no-proto */
        config.__proto__ == null || config.__proto__ === Object.prototype,
        /* eslint-enable no-proto */
        'React.createElement(...): Expected props argument to be a plain object. ' +
        'Properties defined in its prototype chain will be ignored.'
      );
      ref = !hasOwnProperty.call(config, 'ref') ||
        Object.getOwnPropertyDescriptor(config, 'ref').get ? null : config.ref;
      key = !hasOwnProperty.call(config, 'key') ||
        Object.getOwnPropertyDescriptor(config, 'key').get ? null : '' + config.key;
    } else {
      ref = config.ref === undefined ? null : config.ref;
      key = config.key === undefined ? null : '' + config.key;
    }
    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    // Remaining properties are added to a new props object
    for (propName in config) {
      if (hasOwnProperty.call(config, propName) &&
          !RESERVED_PROPS.hasOwnProperty(propName)) {
        props[propName] = config[propName];
      }
    }
  }

  // Children can be more than one argument, and those are transferred onto
  // the newly allocated props object.
  var childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    var childArray = Array(childrenLength);
    for (var i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

  // Resolve default props
  if (type && type.defaultProps) {
    var defaultProps = type.defaultProps;
    for (propName in defaultProps) {
      if (props[propName] === undefined) {
        props[propName] = defaultProps[propName];
      }
    }
  }
  if (__DEV__) {
    // Create dummy `key` and `ref` property to `props` to warn users
    // against its use
    if (typeof props.$$typeof === 'undefined' ||
        props.$$typeof !== REACT_ELEMENT_TYPE) {
      if (!props.hasOwnProperty('key')) {
        Object.defineProperty(props, 'key', {
          get: function() {
            if (!specialPropKeyWarningShown) {
              specialPropKeyWarningShown = true;
              warning(
                false,
                '%s: `key` is not a prop. Trying to access it will result ' +
                  'in `undefined` being returned. If you need to access the same ' +
                  'value within the child component, you should pass it as a different ' +
                  'prop. (https://fb.me/react-special-props)',
                typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
              );
            }
            return undefined;
          },
          configurable: true,
        });
      }
      if (!props.hasOwnProperty('ref')) {
        Object.defineProperty(props, 'ref', {
          get: function() {
            if (!specialPropRefWarningShown) {
              specialPropRefWarningShown = true;
              warning(
                false,
                '%s: `ref` is not a prop. Trying to access it will result ' +
                  'in `undefined` being returned. If you need to access the same ' +
                  'value within the child component, you should pass it as a different ' +
                  'prop. (https://fb.me/react-special-props)',
                typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
              );
            }
            return undefined;
          },
          configurable: true,
        });
      }
    }
  }
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props
  );
};
Example #24
0
  mountComponent: function(rootID, transaction, context) {
    this._context = context;
    this._mountOrder = nextMountID++;
    this._rootNodeID = rootID;

    var publicProps = this._processProps(this._currentElement.props);
    var publicContext = this._processContext(context);

    var Component = ReactNativeComponent.getComponentClassForElement(
      this._currentElement
    );

    // Initialize the public class
    var inst = new Component(publicProps, publicContext);

    if (__DEV__) {
      // This will throw later in _renderValidatedComponent, but add an early
      // warning now to help debugging
      warning(
        inst.render != null,
        '%s(...): No `render` method found on the returned component ' +
        'instance: you may have forgotten to define `render` in your ' +
        'component or you may have accidentally tried to render an element ' +
        'whose type is a function that isn\'t a React component.',
        Component.displayName || Component.name || 'Component'
      );
    }

    // These should be set up in the constructor, but as a convenience for
    // simpler class abstractions, we set them up after the fact.
    inst.props = publicProps;
    inst.context = publicContext;
    inst.refs = emptyObject;

    this._instance = inst;

    // Store a reference from the instance back to the internal representation
    ReactInstanceMap.set(inst, this);

    if (__DEV__) {
      // Since plain JS classes are defined without any special initialization
      // logic, we can not catch common errors early. Therefore, we have to
      // catch them here, at initialization time, instead.
      warning(
        !inst.getInitialState ||
        inst.getInitialState.isReactClassApproved,
        'getInitialState was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Did you mean to define a state property instead?',
        this.getName() || 'a component'
      );
      warning(
        !inst.getDefaultProps ||
        inst.getDefaultProps.isReactClassApproved,
        'getDefaultProps was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Use a static property to define defaultProps instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.propTypes,
        'propTypes was defined as an instance property on %s. Use a static ' +
        'property to define propTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.contextTypes,
        'contextTypes was defined as an instance property on %s. Use a ' +
        'static property to define contextTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        typeof inst.componentShouldUpdate !== 'function',
        '%s has a method called ' +
        'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
        'The name is phrased as a question because the function is ' +
        'expected to return a value.',
        (this.getName() || 'A component')
      );
      warning(
        typeof inst.componentWillRecieveProps !== 'function',
        '%s has a method called ' +
        'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
        (this.getName() || 'A component')
      );
    }

    var initialState = inst.state;
    if (initialState === undefined) {
      inst.state = initialState = null;
    }
    invariant(
      typeof initialState === 'object' && !Array.isArray(initialState),
      '%s.state: must be set to an object or null',
      this.getName() || 'ReactCompositeComponent'
    );

    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;

    var renderedElement;

    var previouslyMounting = ReactLifeCycle.currentlyMountingInstance;
    ReactLifeCycle.currentlyMountingInstance = this;
    try {
      if (inst.componentWillMount) {
        inst.componentWillMount();
        // When mounting, calls to `setState` by `componentWillMount` will set
        // `this._pendingStateQueue` without triggering a re-render.
        if (this._pendingStateQueue) {
          inst.state = this._processPendingState(inst.props, inst.context);
        }
      }

      renderedElement = this._renderValidatedComponent();
    } finally {
      ReactLifeCycle.currentlyMountingInstance = previouslyMounting;
    }

    this._renderedComponent = this._instantiateReactComponent(
      renderedElement,
      this._currentElement.type // The wrapping type
    );

    var markup = ReactReconciler.mountComponent(
      this._renderedComponent,
      rootID,
      transaction,
      this._processChildContext(context)
    );
    if (inst.componentDidMount) {
      transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
    }

    return markup;
  },
Example #25
0
 return abs => {
   process.env.NODE_ENV !== "production" ? warning(abs <= themeTransformer.length - 1, [`@material-ui/system: the value provided (${abs}) overflows.`, `The supported values are: ${JSON.stringify(themeTransformer)}.`, `${abs} > ${themeTransformer.length - 1}, you need to add the missing values.`].join('\n')) : void 0;
   return themeTransformer[abs];
 };
  mountComponent: function(rootID, transaction, context) {
    this._context = context;
    this._mountOrder = nextMountID++;
    this._rootNodeID = rootID;

    var publicProps = this._processProps(this._currentElement.props);
    var publicContext = this._processContext(context);

    var Component = this._currentElement.type;

    // Initialize the public class
    var inst;
    var renderedElement;

    // This is a way to detect if Component is a stateless arrow function
    // component, which is not newable. It might not be 100% reliable but is
    // something we can do until we start detecting that Component extends
    // React.Component. We already assume that typeof Component === 'function'.
    var canInstantiate = 'prototype' in Component;

    if (canInstantiate) {
      if (__DEV__) {
        ReactCurrentOwner.current = this;
        try {
          inst = new Component(publicProps, publicContext, ReactUpdateQueue);
        } finally {
          ReactCurrentOwner.current = null;
        }
      } else {
        inst = new Component(publicProps, publicContext, ReactUpdateQueue);
      }
    }

    if (!canInstantiate || inst === null || inst === false || ReactElement.isValidElement(inst)) {
      renderedElement = inst;
      inst = new StatelessComponent(Component);
    }

    if (__DEV__) {
      // This will throw later in _renderValidatedComponent, but add an early
      // warning now to help debugging
      if (inst.render == null) {
        warning(
          false,
          '%s(...): No `render` method found on the returned component ' +
          'instance: you may have forgotten to define `render`, returned ' +
          'null/false from a stateless component, or tried to render an ' +
          'element whose type is a function that isn\'t a React component.',
          Component.displayName || Component.name || 'Component'
        );
      } else {
        // We support ES6 inheriting from React.Component, the module pattern,
        // and stateless components, but not ES6 classes that don't extend
        warning(
          (Component.prototype && Component.prototype.isReactComponent) ||
            !canInstantiate ||
            !(inst instanceof Component),
          '%s(...): React component classes must extend React.Component.',
          Component.displayName || Component.name || 'Component'
        );
      }
    }

    // These should be set up in the constructor, but as a convenience for
    // simpler class abstractions, we set them up after the fact.
    inst.props = publicProps;
    inst.context = publicContext;
    inst.refs = emptyObject;
    inst.updater = ReactUpdateQueue;

    this._instance = inst;

    // Store a reference from the instance back to the internal representation
    ReactInstanceMap.set(inst, this);

    if (__DEV__) {
      // Since plain JS classes are defined without any special initialization
      // logic, we can not catch common errors early. Therefore, we have to
      // catch them here, at initialization time, instead.
      warning(
        !inst.getInitialState ||
        inst.getInitialState.isReactClassApproved,
        'getInitialState was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Did you mean to define a state property instead?',
        this.getName() || 'a component'
      );
      warning(
        !inst.getDefaultProps ||
        inst.getDefaultProps.isReactClassApproved,
        'getDefaultProps was defined on %s, a plain JavaScript class. ' +
        'This is only supported for classes created using React.createClass. ' +
        'Use a static property to define defaultProps instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.propTypes,
        'propTypes was defined as an instance property on %s. Use a static ' +
        'property to define propTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        !inst.contextTypes,
        'contextTypes was defined as an instance property on %s. Use a ' +
        'static property to define contextTypes instead.',
        this.getName() || 'a component'
      );
      warning(
        typeof inst.componentShouldUpdate !== 'function',
        '%s has a method called ' +
        'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
        'The name is phrased as a question because the function is ' +
        'expected to return a value.',
        (this.getName() || 'A component')
      );
      warning(
        typeof inst.componentDidUnmount !== 'function',
        '%s has a method called ' +
        'componentDidUnmount(). But there is no such lifecycle method. ' +
        'Did you mean componentWillUnmount()?',
        this.getName() || 'A component'
      );
      warning(
        typeof inst.componentWillRecieveProps !== 'function',
        '%s has a method called ' +
        'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
        (this.getName() || 'A component')
      );
    }

    var initialState = inst.state;
    if (initialState === undefined) {
      inst.state = initialState = null;
    }
    invariant(
      typeof initialState === 'object' && !Array.isArray(initialState),
      '%s.state: must be set to an object or null',
      this.getName() || 'ReactCompositeComponent'
    );

    this._pendingStateQueue = null;
    this._pendingReplaceState = false;
    this._pendingForceUpdate = false;

    if (inst.componentWillMount) {
      inst.componentWillMount();
      // When mounting, calls to `setState` by `componentWillMount` will set
      // `this._pendingStateQueue` without triggering a re-render.
      if (this._pendingStateQueue) {
        inst.state = this._processPendingState(inst.props, inst.context);
      }
    }

    // If not a stateless component, we now render
    if (renderedElement === undefined) {
      renderedElement = this._renderValidatedComponent();
    }

    this._renderedComponent = this._instantiateReactComponent(
      renderedElement
    );

    var markup = ReactReconciler.mountComponent(
      this._renderedComponent,
      rootID,
      transaction,
      this._processChildContext(context)
    );
    if (inst.componentDidMount) {
      transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
    }

    return markup;
  },
Example #27
0
export function mergeAndPrefix(...args) {
  warning(false, 'Use of mergeAndPrefix() has been deprecated. ' +
    'Please use mergeStyles() for merging styles, and then prepareStyles() for prefixing and ensuring direction.');
  return autoPrefix.all(mergeStyles(...args));
}
  updateComponent: function(
    transaction,
    prevParentElement,
    nextParentElement,
    prevUnmaskedContext,
    nextUnmaskedContext
  ) {
    var inst = this._instance;

    var nextContext = this._context === nextUnmaskedContext ?
      inst.context :
      this._processContext(nextUnmaskedContext);
    var nextProps;

    // Distinguish between a props update versus a simple state update
    if (prevParentElement === nextParentElement) {
      // Skip checking prop types again -- we don't read inst.props to avoid
      // warning for DOM component props in this upgrade
      nextProps = nextParentElement.props;
    } else {
      nextProps = this._processProps(nextParentElement.props);
      // An update here will schedule an update but immediately set
      // _pendingStateQueue which will ensure that any state updates gets
      // immediately reconciled instead of waiting for the next batch.

      if (inst.componentWillReceiveProps) {
        inst.componentWillReceiveProps(nextProps, nextContext);
      }
    }

    var nextState = this._processPendingState(nextProps, nextContext);

    var shouldUpdate =
      this._pendingForceUpdate ||
      !inst.shouldComponentUpdate ||
      inst.shouldComponentUpdate(nextProps, nextState, nextContext);

    if (__DEV__) {
      warning(
        typeof shouldUpdate !== 'undefined',
        '%s.shouldComponentUpdate(): Returned undefined instead of a ' +
        'boolean value. Make sure to return true or false.',
        this.getName() || 'ReactCompositeComponent'
      );
    }

    if (shouldUpdate) {
      this._pendingForceUpdate = false;
      // Will set `this.props`, `this.state` and `this.context`.
      this._performComponentUpdate(
        nextParentElement,
        nextProps,
        nextState,
        nextContext,
        transaction,
        nextUnmaskedContext
      );
    } else {
      // If it's determined that a component should not update, we still want
      // to set props and state but we shortcut the rest of the update.
      this._currentElement = nextParentElement;
      this._context = nextUnmaskedContext;
      inst.props = nextProps;
      inst.state = nextState;
      inst.context = nextContext;
    }
  },
/**
 * Given an `element` create an instance that will actually be mounted.
 *
 * @param {object} element
 * @param {*} parentCompositeType The composite type that resolved this.
 * @return {object} A new instance of the element's constructor.
 * @protected
 */
function instantiateReactComponent(element, parentCompositeType) {
  var instance;

  if (__DEV__) {
    warning(
      element && (typeof element.type === 'function' ||
                     typeof element.type === 'string'),
      'Only functions or strings can be mounted as React components.'
    );

    // Resolve mock instances
    if (element.type._mockedReactClassConstructor) {
      // If this is a mocked class, we treat the legacy factory as if it was the
      // class constructor for future proofing unit tests. Because this might
      // be mocked as a legacy factory, we ignore any warnings triggerd by
      // this temporary hack.
      ReactLegacyElement._isLegacyCallWarningEnabled = false;
      try {
        instance = new element.type._mockedReactClassConstructor(
          element.props
        );
      } finally {
        ReactLegacyElement._isLegacyCallWarningEnabled = true;
      }

      // If the mock implementation was a legacy factory, then it returns a
      // element. We need to turn this into a real component instance.
      if (ReactElement.isValidElement(instance)) {
        instance = new instance.type(instance.props);
      }

      var render = instance.render;
      if (!render) {
        // For auto-mocked factories, the prototype isn't shimmed and therefore
        // there is no render function on the instance. We replace the whole
        // component with an empty component instance instead.
        element = ReactEmptyComponent.getEmptyComponent();
      } else {
        if (render._isMockFunction && !render._getMockImplementation()) {
          // Auto-mocked components may have a prototype with a mocked render
          // function. For those, we'll need to mock the result of the render
          // since we consider undefined to be invalid results from render.
          render.mockImplementation(
            ReactEmptyComponent.getEmptyComponent
          );
        }
        instance.construct(element);
        return instance;
      }
    }
  }

  // Special case string values
  if (typeof element.type === 'string') {
    instance = ReactNativeComponent.createInstanceForTag(
      element.type,
      element.props,
      parentCompositeType
    );
  } else {
    // Normal case for non-mocks and non-strings
    instance = new element.type(element.props);
  }

  if (__DEV__) {
    warning(
      typeof instance.construct === 'function' &&
      typeof instance.mountComponent === 'function' &&
      typeof instance.receiveComponent === 'function',
      'Only React Components can be mounted.'
    );
  }

  // This actually sets up the internal instance. This will become decoupled
  // from the public instance in a future diff.
  instance.construct(element);

  return instance;
}
Example #30
0
  findComponentRoot: function(ancestorNode, targetID) {
    var firstChildren = findComponentRootReusableArray;
    var childIndex = 0;

    var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;

    if (__DEV__) {
      // This will throw on the next line; give an early warning
      warning(
        deepestAncestor != null,
        'React can\'t find the root component node for data-reactid value ' +
        '`%s`. If you\'re seeing this message, it probably means that ' +
        'you\'ve loaded two copies of React on the page. At this time, only ' +
        'a single copy of React can be loaded at a time.',
        targetID
      );
    }

    firstChildren[0] = deepestAncestor.firstChild;
    firstChildren.length = 1;

    while (childIndex < firstChildren.length) {
      var child = firstChildren[childIndex++];
      var targetChild;

      while (child) {
        var childID = ReactMount.getID(child);
        if (childID) {
          // Even if we find the node we're looking for, we finish looping
          // through its siblings to ensure they're cached so that we don't have
          // to revisit this node again. Otherwise, we make n^2 calls to getID
          // when visiting the many children of a single node in order.

          if (targetID === childID) {
            targetChild = child;
          } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {
            // If we find a child whose ID is an ancestor of the given ID,
            // then we can be sure that we only want to search the subtree
            // rooted at this child, so we can throw out the rest of the
            // search state.
            firstChildren.length = childIndex = 0;
            firstChildren.push(child.firstChild);
          }

        } else {
          // If this child had no ID, then there's a chance that it was
          // injected automatically by the browser, as when a `<table>`
          // element sprouts an extra `<tbody>` child as a side effect of
          // `.innerHTML` parsing. Optimistically continue down this
          // branch, but not before examining the other siblings.
          firstChildren.push(child.firstChild);
        }

        child = child.nextSibling;
      }

      if (targetChild) {
        // Emptying firstChildren/findComponentRootReusableArray is
        // not necessary for correctness, but it helps the GC reclaim
        // any nodes that were left at the end of the search.
        firstChildren.length = 0;

        return targetChild;
      }
    }

    firstChildren.length = 0;

    invariant(
      false,
      'findComponentRoot(..., %s): Unable to find element. This probably ' +
      'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
      'usually due to forgetting a <tbody> when using tables, nesting tags ' +
      'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' +
      'parent. ' +
      'Try inspecting the child nodes of the element with React ID `%s`.',
      targetID,
      ReactMount.getID(ancestorNode)
    );
  },