Example #1
0
 performUpdateIfNecessary: function(
   internalInstance,
   transaction,
   updateBatchNumber
 ) {
   if (internalInstance._updateBatchNumber !== updateBatchNumber) {
     // The component's enqueued batch number should always be the current
     // batch or the following one.
     warning(
       internalInstance._updateBatchNumber == null ||
       internalInstance._updateBatchNumber === updateBatchNumber + 1,
       'performUpdateIfNecessary: Unexpected batch number (current %s, ' +
       'pending %s)',
       updateBatchNumber,
       internalInstance._updateBatchNumber
     );
     return;
   }
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onBeforeUpdateComponent(
         internalInstance._debugID,
         internalInstance._currentElement
       );
     }
   }
   internalInstance.performUpdateIfNecessary(transaction);
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onUpdateComponent(
         internalInstance._debugID
       );
     }
   }
 },
Example #2
0
  _renderNewRootComponent: function(
    nextElement,
    container,
    shouldReuseMarkup,
    context
  ) {
    if (__DEV__) {
      ReactInstrumentation.debugTool.onBeginFlush();
    }

    // Various parts of our code (such as ReactCompositeComponent's
    // _renderValidatedComponent) assume that calls to render aren't nested;
    // verify that that's the case.
    warning(
      ReactCurrentOwner.current == null,
      '_renderNewRootComponent(): 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(
      container && (
        container.nodeType === ELEMENT_NODE_TYPE ||
        container.nodeType === DOC_NODE_TYPE ||
        container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE
      ),
      '_registerComponent(...): Target container is not a DOM element.'
    );

    ReactBrowserEventEmitter.ensureScrollValueMonitoring();
    var componentInstance = instantiateReactComponent(nextElement, false);

    // The initial render is synchronous but any updates that happen during
    // rendering, in componentWillMount or componentDidMount, will be batched
    // according to the current batching strategy.

    ReactUpdates.batchedUpdates(
      batchedMountComponentIntoNode,
      componentInstance,
      container,
      shouldReuseMarkup,
      context
    );

    var wrapperID = componentInstance._instance.rootID;
    instancesByReactRootID[wrapperID] = componentInstance;

    if (__DEV__) {
      // The instance here is TopLevelWrapper so we report mount for its child.
      ReactInstrumentation.debugTool.onMountRootComponent(
        componentInstance._renderedComponent._debugID
      );
      ReactInstrumentation.debugTool.onEndFlush();
    }

    return componentInstance;
  },
  _renderValidatedComponentWithoutOwnerOrContext: function() {
    var inst = this._instance;

    if (__DEV__) {
      if (this._debugID !== 0) {
        ReactInstrumentation.debugTool.onBeginLifeCycleTimer(
          this._debugID,
          'render'
        );
      }
    }
    var renderedComponent = inst.render();
    if (__DEV__) {
      if (this._debugID !== 0) {
        ReactInstrumentation.debugTool.onEndLifeCycleTimer(
          this._debugID,
          'render'
        );
      }
    }

    if (__DEV__) {
      // We allow auto-mocks to proceed as if they're returning null.
      if (renderedComponent === undefined &&
          inst.render._isMockFunction) {
        // This is probably bad practice. Consider warning here and
        // deprecating this convenience.
        renderedComponent = null;
      }
    }

    return renderedComponent;
  },
  receiveComponent: function receiveComponent(internalInstance, nextElement, transaction, context) {
    var prevElement = internalInstance._currentElement;

    if (nextElement === prevElement && context === internalInstance._context) {
      return;
    }

    if (__DEV__) {
      if (internalInstance._debugID !== 0) {
        ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement);
      }
    }

    var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement);

    if (refsChanged) {
      ReactRef.detachRefs(internalInstance, prevElement);
    }

    internalInstance.receiveComponent(nextElement, transaction, context);

    if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {
      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
    }

    if (__DEV__) {
      if (internalInstance._debugID !== 0) {
        ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
      }
    }
  },
Example #5
0
  receiveComponent: function(
    internalInstance, nextElement, transaction, context
  ) {
    var prevElement = internalInstance._currentElement;

    if (nextElement === prevElement &&
        context === internalInstance._context
      ) {
      // Since elements are immutable after the owner is rendered,
      // we can do a cheap identity compare here to determine if this is a
      // superfluous reconcile. It's possible for state to be mutable but such
      // change should trigger an update of the owner which would recreate
      // the element. We explicitly check for the existence of an owner since
      // it's possible for an element created outside a composite to be
      // deeply mutated and reused.

      // TODO: Bailing out early is just a perf optimization right?
      // TODO: Removing the return statement should affect correctness?
      return;
    }

    if (__DEV__) {
      if (internalInstance._debugID !== 0) {
        ReactInstrumentation.debugTool.onBeginReconcilerTimer(
          internalInstance._debugID,
          'receiveComponent'
        );
      }
    }

    var refsChanged = ReactRef.shouldUpdateRefs(
      prevElement,
      nextElement
    );

    if (refsChanged) {
      ReactRef.detachRefs(internalInstance, prevElement);
    }

    internalInstance.receiveComponent(nextElement, transaction, context);

    if (refsChanged &&
        internalInstance._currentElement &&
        internalInstance._currentElement.ref != null) {
      transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
    }

    if (__DEV__) {
      if (internalInstance._debugID !== 0) {
        ReactInstrumentation.debugTool.onEndReconcilerTimer(
          internalInstance._debugID,
          'receiveComponent'
        );
        ReactInstrumentation.debugTool.onUpdateComponent(
          internalInstance._debugID
        );
      }
    }
  },
  _processChildContext: function(currentContext) {
    var Component = this._currentElement.type;
    var inst = this._instance;
    var childContext;

    if (typeof inst.getChildContext === 'function') {
      if (__DEV__) {
        ReactInstrumentation.debugTool.onBeginProcessingChildContext();
        try {
          childContext = inst.getChildContext();
        } finally {
          ReactInstrumentation.debugTool.onEndProcessingChildContext();
        }
      } else {
        childContext = inst.getChildContext();
      }

      invariant(
        typeof Component.childContextTypes === 'object',
        '%s.getChildContext(): childContextTypes must be defined in order to ' +
        'use getChildContext().',
        this.getName() || 'ReactCompositeComponent'
      );
      if (__DEV__) {
        this._checkContextTypes(
          Component.childContextTypes,
          childContext,
          'childContext'
        );
      }
      for (var name in childContext) {
        invariant(
          name in Component.childContextTypes,
          '%s.getChildContext(): key "%s" is not defined in childContextTypes.',
          this.getName() || 'ReactCompositeComponent',
          name
        );
      }
      return Object.assign({}, currentContext, childContext);
    } else {
      if (__DEV__) {
        const componentName = this.getName();
        
        if (!warningAboutMissingGetChildContext[componentName]) {
          warningAboutMissingGetChildContext[componentName] = true;
          warning(
            !Component.childContextTypes,
            '%s.childContextTypes is specified but there is no getChildContext() method ' +
            'on the instance. You can either define getChildContext() on %s or remove ' +
            'childContextTypes from it.',
            componentName,
            componentName,
          );
        }
      }
    }
    return currentContext;
  },
Example #7
0
 setContentChildForInstrumentation = function(contentToUse) {
   var debugID = this._debugID;
   var contentDebugID = debugID + '#text';
   this._contentDebugID = contentDebugID;
   ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text');
   ReactInstrumentation.debugTool.onSetText(contentDebugID, '' + contentToUse);
   ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
   ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
 };
Example #8
0
  _updateDOMChildren: function(lastProps, nextProps, transaction, context) {
    var lastContent =
      CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
    var nextContent =
      CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;

    var lastHtml =
      lastProps.dangerouslySetInnerHTML &&
      lastProps.dangerouslySetInnerHTML.__html;
    var nextHtml =
      nextProps.dangerouslySetInnerHTML &&
      nextProps.dangerouslySetInnerHTML.__html;

    // Note the use of `!=` which checks for null or undefined.
    var lastChildren = lastContent != null ? null : lastProps.children;
    var nextChildren = nextContent != null ? null : nextProps.children;

    // If we're switching from children to content/html or vice versa, remove
    // the old content
    var lastHasContentOrHtml = lastContent != null || lastHtml != null;
    var nextHasContentOrHtml = nextContent != null || nextHtml != null;
    if (lastChildren != null && nextChildren == null) {
      this.updateChildren(null, transaction, context);
    } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
      this.updateTextContent('');
      if (__DEV__) {
        ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
      }
    }

    if (nextContent != null) {
      if (lastContent !== nextContent) {
        this.updateTextContent('' + nextContent);
        if (__DEV__) {
          this._contentDebugID = this._debugID + '#text';
          setContentChildForInstrumentation.call(this, nextContent);
        }
      }
    } else if (nextHtml != null) {
      if (lastHtml !== nextHtml) {
        this.updateMarkup('' + nextHtml);
      }
      if (__DEV__) {
        ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
      }
    } else if (nextChildren != null) {
      if (__DEV__) {
        if (this._contentDebugID) {
          ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
          this._contentDebugID = null;
        }
      }

      this.updateChildren(nextChildren, transaction, context);
    }
  },
Example #9
0
  setContentChildForInstrumentation = function(content) {
    var hasExistingContent = this._contentDebugID != null;
    var debugID = this._debugID;
    var contentDebugID = debugID + '#text';

    if (content == null) {
      if (hasExistingContent) {
        ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
      }
      this._contentDebugID = null;
      return;
    }

    this._contentDebugID = contentDebugID;
    var text = '' + content;

    ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text');
    ReactInstrumentation.debugTool.onSetParent(contentDebugID, debugID);
    ReactInstrumentation.debugTool.onSetText(contentDebugID, text);

    if (hasExistingContent) {
      ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content);
      ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID);
    } else {
      ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content);
      ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
      ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
    }
  };
  _updateRenderedComponent: function(transaction, context) {
    var prevComponentInstance = this._renderedComponent;
    var prevRenderedElement = prevComponentInstance._currentElement;
    var nextRenderedElement = this._renderValidatedComponent();
    if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
      ReactReconciler.receiveComponent(
        prevComponentInstance,
        nextRenderedElement,
        transaction,
        this._processChildContext(context)
      );
    } else {
      var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance);
      ReactReconciler.unmountComponent(prevComponentInstance, false);

      var nodeType = ReactNodeTypes.getType(nextRenderedElement);
      this._renderedNodeType = nodeType;
      var child = this._instantiateReactComponent(
        nextRenderedElement,
        nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
      );
      this._renderedComponent = child;
      if (__DEV__) {
        if (child._debugID !== 0 && this._debugID !== 0) {
          ReactInstrumentation.debugTool.onSetParent(
            child._debugID,
            this._debugID
          );
        }
      }

      var nextMarkup = ReactReconciler.mountComponent(
        child,
        transaction,
        this._hostParent,
        this._hostContainerInfo,
        this._processChildContext(context)
      );

      if (__DEV__) {
        if (this._debugID !== 0) {
          ReactInstrumentation.debugTool.onSetChildren(
            this._debugID,
            child._debugID !== 0 ? [child._debugID] : []
          );
        }
      }

      this._replaceNodeWithMarkup(
        oldHostNode,
        nextMarkup,
        prevComponentInstance
      );
    }
  },
 unmountComponent: function unmountComponent(internalInstance, safely) {
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID);
     }
   }
   ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
   internalInstance.unmountComponent(safely);
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID);
     }
   }
 },
 _constructComponentWithoutOwner: function(
   doConstruct,
   publicProps,
   publicContext,
   updateQueue
 ) {
   var Component = this._currentElement.type;
   var instanceOrElement;
   if (doConstruct) {
     if (__DEV__) {
       if (this._debugID !== 0) {
         ReactInstrumentation.debugTool.onBeginLifeCycleTimer(
           this._debugID,
           'ctor'
         );
       }
     }
     instanceOrElement = new Component(publicProps, publicContext, updateQueue);
     if (__DEV__) {
       if (this._debugID !== 0) {
         ReactInstrumentation.debugTool.onEndLifeCycleTimer(
           this._debugID,
           'ctor'
         );
       }
     }
   } else {
     // This can still be an instance in case of factory components
     // but we'll count this as time spent rendering as the more common case.
     if (__DEV__) {
       if (this._debugID !== 0) {
         ReactInstrumentation.debugTool.onBeginLifeCycleTimer(
           this._debugID,
           'render'
         );
       }
     }
     instanceOrElement = Component(publicProps, publicContext, updateQueue);
     if (__DEV__) {
       if (this._debugID !== 0) {
         ReactInstrumentation.debugTool.onEndLifeCycleTimer(
           this._debugID,
           'render'
         );
       }
     }
   }
   return instanceOrElement;
 },
// Separated into a function to contain deoptimizations caused by try/finally.
function measureLifeCyclePerf(fn, debugID, timerType) {
  if (debugID === 0) {
    // Top-level wrappers (see ReactMount) and empty components (see
    // ReactDOMEmptyComponent) are invisible to hooks and devtools.
    // Both are implementation details that should go away in the future.
    return fn();
  }

  ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType);
  try {
    return fn();
  } finally {
    ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType);
  }
}
Example #14
0
  receiveComponent: function(nextText, transaction) {
    if (nextText !== this._currentElement) {
      this._currentElement = nextText;
      var nextStringText = '' + nextText;
      if (nextStringText !== this._stringText) {
        // TODO: Save this as pending props and use performUpdateIfNecessary
        // and/or updateComponent to do the actual update for consistency with
        // other component types?
        this._stringText = nextStringText;
        var commentNodes = this.getHostNode();
        DOMChildrenOperations.replaceDelimitedText(
          commentNodes[0],
          commentNodes[1],
          nextStringText
        );

        if (__DEV__) {
          ReactInstrumentation.debugTool.onSetText(
            this._debugID,
            nextStringText
          );
        }
      }
    }
  },
Example #15
0
  enqueueSetState: function(publicInstance, partialState) {
    if (__DEV__) {
      ReactInstrumentation.debugTool.onSetState();
      warning(
        partialState != null,
        'setState(...): You passed an undefined or null state object; ' +
        'instead, use forceUpdate().'
      );
    }

    var internalInstance = getInternalInstanceReadyForUpdate(
      publicInstance,
      'setState'
    );

    if (!internalInstance) {
      return;
    }

    var queue =
      internalInstance._pendingStateQueue ||
      (internalInstance._pendingStateQueue = []);
    queue.push(partialState);

    enqueueUpdate(internalInstance);
  },
  deleteValueForProperty: function(node, name) {
    var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ?
        DOMProperty.properties[name] : null;
    if (propertyInfo) {
      var mutationMethod = propertyInfo.mutationMethod;
      if (mutationMethod) {
        mutationMethod(node, undefined);
      } else if (propertyInfo.mustUseProperty) {
        var propName = propertyInfo.propertyName;
        if (propertyInfo.hasBooleanValue) {
          // No HAS_SIDE_EFFECTS logic here, only `value` has it and is string.
          node[propName] = false;
        } else {
          if (!propertyInfo.hasSideEffects ||
              ('' + node[propName]) !== '') {
            node[propName] = '';
          }
        }
      } else {
        node.removeAttribute(propertyInfo.attributeName);
      }
    } else if (DOMProperty.isCustomAttribute(name)) {
      node.removeAttribute(name);
    }

    if (__DEV__) {
      ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name);
      ReactInstrumentation.debugTool.onNativeOperation(
        ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
        'remove attribute',
        name
      );
    }
  },
Example #17
0
function replaceDelimitedText(openingComment, closingComment, stringText) {
  var parentNode = openingComment.parentNode;
  var nodeAfterComment = openingComment.nextSibling;
  if (nodeAfterComment === closingComment) {
    // There are no text nodes between the opening and closing comments; insert
    // a new one if stringText isn't empty.
    if (stringText) {
      insertChildAt(
        parentNode,
        document.createTextNode(stringText),
        nodeAfterComment
      );
    }
  } else {
    if (stringText) {
      // Set the text content of the first node after the opening comment, and
      // remove all following nodes up until the closing comment.
      setTextContent(nodeAfterComment, stringText);
      removeDelimitedText(parentNode, nodeAfterComment, closingComment);
    } else {
      removeDelimitedText(parentNode, openingComment, closingComment);
    }
  }

  if (__DEV__) {
    ReactInstrumentation.debugTool.onNativeOperation(
      ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID,
      'replace text',
      stringText
    );
  }
}
  _updateRenderedComponentWithNextElement: function(
    transaction,
    context,
    nextRenderedElement,
    safely,
  ) {
    var prevComponentInstance = this._renderedComponent;
    var prevRenderedElement = prevComponentInstance._currentElement;

    var debugID = 0;
    if (__DEV__) {
      debugID = this._debugID;
    }

    if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
      ReactReconciler.receiveComponent(
        prevComponentInstance,
        nextRenderedElement,
        transaction,
        this._processChildContext(context),
      );
    } else {
      var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance);
      var nodeType = ReactNodeTypes.getType(nextRenderedElement);
      this._renderedNodeType = nodeType;
      var child = this._instantiateReactComponent(
        nextRenderedElement,
        nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */,
      );
      this._renderedComponent = child;

      var nextMarkup = ReactReconciler.mountComponent(
        child,
        transaction,
        this._hostParent,
        this._hostContainerInfo,
        this._processChildContext(context),
        debugID,
      );

      ReactReconciler.unmountComponent(
        prevComponentInstance,
        safely,
        false /* skipLifecycle */,
      );

      if (__DEV__) {
        if (debugID !== 0) {
          var childDebugIDs = child._debugID !== 0 ? [child._debugID] : [];
          ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs);
        }
      }

      this._replaceNodeWithMarkup(
        oldHostNode,
        nextMarkup,
        prevComponentInstance,
      );
    }
  },
  deleteValueForProperty: function(node, name) {
    var propertyInfo = DOMProperty.properties.hasOwnProperty(name)
      ? DOMProperty.properties[name]
      : null;
    if (propertyInfo) {
      var mutationMethod = propertyInfo.mutationMethod;
      if (mutationMethod) {
        mutationMethod(node, undefined);
      } else if (propertyInfo.mustUseProperty) {
        var propName = propertyInfo.propertyName;
        if (propertyInfo.hasBooleanValue) {
          node[propName] = false;
        } else {
          node[propName] = '';
        }
      } else {
        node.removeAttribute(propertyInfo.attributeName);
      }
    } else if (DOMProperty.isCustomAttribute(name)) {
      node.removeAttribute(name);
    }

    if (__DEV__) {
      ReactInstrumentation.debugTool.onHostOperation({
        instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
        type: 'remove attribute',
        payload: name,
      });
    }
  },
Example #20
0
  enqueueSetState: function(publicInstance, partialState, callback, callerName) {
    if (__DEV__) {
      ReactInstrumentation.debugTool.onSetState();
      warning(
        partialState != null,
        'setState(...): You passed an undefined or null state object; ' +
        'instead, use forceUpdate().'
      );
    }

    var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);

    if (!internalInstance) {
      return;
    }

    var queue =
      internalInstance._pendingStateQueue ||
      (internalInstance._pendingStateQueue = []);
    queue.push(partialState);

    if (callback) {
      callback = callback === undefined ? null : callback;
      if (__DEV__) {
        warnOnInvalidCallback(callback, callerName);
      }
      if (internalInstance._pendingCallbacks) {
        internalInstance._pendingCallbacks.push(callback);
      } else {
        internalInstance._pendingCallbacks = [callback];
      }
    }

    enqueueUpdate(internalInstance);
  },
function invokeComponentDidUpdateWithTimer(prevProps, prevState, prevContext) {
  var publicInstance = this._instance;
  if (this._debugID !== 0) {
    ReactInstrumentation.debugTool.onBeginLifeCycleTimer(
      this._debugID,
      'componentDidUpdate'
    );
  }
  publicInstance.componentDidUpdate(prevProps, prevState, prevContext);
  if (this._debugID !== 0) {
    ReactInstrumentation.debugTool.onEndLifeCycleTimer(
      this._debugID,
      'componentDidUpdate'
    );
  }
}
function invokeComponentDidMountWithTimer() {
  var publicInstance = this._instance;
  if (this._debugID !== 0) {
    ReactInstrumentation.debugTool.onBeginLifeCycleTimer(
      this._debugID,
      'componentDidMount'
    );
  }
  publicInstance.componentDidMount();
  if (this._debugID !== 0) {
    ReactInstrumentation.debugTool.onEndLifeCycleTimer(
      this._debugID,
      'componentDidMount'
    );
  }
}
  performInitialMountWithErrorHandling: function(
    renderedElement,
    hostParent,
    hostContainerInfo,
    transaction,
    context
  ) {
    var markup;
    var checkpoint = transaction.checkpoint();
    try {
      markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
    } catch (e) {
      if (__DEV__) {
        if (this._debugID !== 0) {
          ReactInstrumentation.debugTool.onError();
        }
      }
      // Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint
      transaction.rollback(checkpoint);
      this._instance.unstable_handleError(e);
      if (this._pendingStateQueue) {
        this._instance.state = this._processPendingState(this._instance.props, this._instance.context);
      }
      checkpoint = transaction.checkpoint();

      this._renderedComponent.unmountComponent(true);
      transaction.rollback(checkpoint);

      // Try again - we've informed the component about the error, so they can render an error message this time.
      // If this throws again, the error will bubble up (and can be caught by a higher error boundary).
      markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
    }
    return markup;
  },
  mountComponent: function(transaction, nativeParent, nativeContainerInfo, context) {
    if (__DEV__) {
      ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
    }

    // TODO: nativeParent should have this context already. Stop abusing context.
    invariant(
      context.isInAParentText,
      'RawText "%s" must be wrapped in an explicit <Text> component.',
      this._stringText
    );
    this._nativeParent = nativeParent;
    var tag = ReactNativeTagHandles.allocateTag();
    this._rootNodeID = tag;
    var nativeTopRootTag = nativeContainerInfo._tag;
    UIManager.createView(
      tag,
      'RCTRawText',
      nativeTopRootTag,
      {text: this._stringText}
    );

    ReactNativeComponentTree.precacheNode(this, tag);

    return tag;
  },
Example #25
0
  mountComponent: function(
    transaction,
    hostParent,
    hostContainerInfo,
    context
  ) {
    if (__DEV__) {
      ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);

      var parentInfo;
      if (hostParent != null) {
        parentInfo = hostParent._ancestorInfo;
      } else if (hostContainerInfo != null) {
        parentInfo = hostContainerInfo._ancestorInfo;
      }
      if (parentInfo) {
        // parentInfo should always be present except for the top-level
        // component when server rendering
        validateDOMNesting('#text', this, parentInfo);
      }
    }

    var domID = hostContainerInfo._idCounter++;
    var openingValue = ' react-text: ' + domID + ' ';
    var closingValue = ' /react-text ';
    this._domID = domID;
    this._hostParent = hostParent;
    if (transaction.useCreateElement) {
      var ownerDocument = hostContainerInfo._ownerDocument;
      var openingComment = ownerDocument.createComment(openingValue);
      var closingComment = ownerDocument.createComment(closingValue);
      var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment());
      DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment));
      if (this._stringText) {
        DOMLazyTree.queueChild(
          lazyTree,
          DOMLazyTree(ownerDocument.createTextNode(this._stringText))
        );
      }
      DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment));
      ReactDOMComponentTree.precacheNode(this, openingComment);
      this._closingComment = closingComment;
      return lazyTree;
    } else {
      var escapedText = escapeTextContentForBrowser(this._stringText);

      if (transaction.renderToStaticMarkup) {
        // Normally we'd wrap this between comment nodes for the reasons stated
        // above, but since this is a situation where React won't take over
        // (static pages), we can simply return the text as it is.
        return escapedText;
      }

      return (
        '<!--' + openingValue + '-->' + escapedText +
        '<!--' + closingValue + '-->'
      );
    }
  },
Example #26
0
 dangerouslyReplaceNodeWithMarkup = function(oldChild, markup, prevInstance) {
   Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup);
   ReactInstrumentation.debugTool.onNativeOperation(
     prevInstance._debugID,
     'replace with',
     markup.toString()
   );
 };
 mountComponent: function mountComponent(internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID) {
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID);
     }
   }
   var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID);
   if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {
     transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
   }
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID);
     }
   }
   return markup;
 },
 performUpdateIfNecessary: function performUpdateIfNecessary(internalInstance, transaction, updateBatchNumber) {
   if (internalInstance._updateBatchNumber !== updateBatchNumber) {
     warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber);
     return;
   }
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement);
     }
   }
   internalInstance.performUpdateIfNecessary(transaction);
   if (__DEV__) {
     if (internalInstance._debugID !== 0) {
       ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
     }
   }
 }
Example #29
0
 setParentForInstrumentation = function(child) {
   if (child._debugID !== 0) {
     ReactInstrumentation.debugTool.onSetParent(
       child._debugID,
       getDebugID(this)
     );
   }
 };
Example #30
0
var ShallowComponentWrapper = function(element) {
  // TODO: Consolidate with instantiateReactComponent
  this._debugID = nextDebugID++;
  var displayName = element.type.displayName || element.type.name || 'Unknown';
  ReactInstrumentation.debugTool.onSetDisplayName(this._debugID, displayName);

  this.construct(element);
};