diff options
Diffstat (limited to 'node_modules/react-dom/lib/ReactMount.js')
-rw-r--r-- | node_modules/react-dom/lib/ReactMount.js | 537 |
1 files changed, 0 insertions, 537 deletions
diff --git a/node_modules/react-dom/lib/ReactMount.js b/node_modules/react-dom/lib/ReactMount.js deleted file mode 100644 index b0f7ceb99..000000000 --- a/node_modules/react-dom/lib/ReactMount.js +++ /dev/null @@ -1,537 +0,0 @@ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -'use strict'; - -var _prodInvariant = require('./reactProdInvariant'); - -var DOMLazyTree = require('./DOMLazyTree'); -var DOMProperty = require('./DOMProperty'); -var React = require('react/lib/React'); -var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter'); -var ReactCurrentOwner = require('react/lib/ReactCurrentOwner'); -var ReactDOMComponentTree = require('./ReactDOMComponentTree'); -var ReactDOMContainerInfo = require('./ReactDOMContainerInfo'); -var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags'); -var ReactFeatureFlags = require('./ReactFeatureFlags'); -var ReactInstanceMap = require('./ReactInstanceMap'); -var ReactInstrumentation = require('./ReactInstrumentation'); -var ReactMarkupChecksum = require('./ReactMarkupChecksum'); -var ReactReconciler = require('./ReactReconciler'); -var ReactUpdateQueue = require('./ReactUpdateQueue'); -var ReactUpdates = require('./ReactUpdates'); - -var emptyObject = require('fbjs/lib/emptyObject'); -var instantiateReactComponent = require('./instantiateReactComponent'); -var invariant = require('fbjs/lib/invariant'); -var setInnerHTML = require('./setInnerHTML'); -var shouldUpdateReactComponent = require('./shouldUpdateReactComponent'); -var warning = require('fbjs/lib/warning'); - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var ROOT_ATTR_NAME = DOMProperty.ROOT_ATTRIBUTE_NAME; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; -var DOCUMENT_FRAGMENT_NODE_TYPE = 11; - -var instancesByReactRootID = {}; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode(wrapperInstance, container, transaction, shouldReuseMarkup, context) { - var markerName; - if (ReactFeatureFlags.logTopLevelRenders) { - var wrappedElement = wrapperInstance._currentElement.props.child; - var type = wrappedElement.type; - markerName = 'React mount: ' + (typeof type === 'string' ? type : type.displayName || type.name); - console.time(markerName); - } - - var markup = ReactReconciler.mountComponent(wrapperInstance, transaction, null, ReactDOMContainerInfo(wrapperInstance, container), context, 0 /* parentDebugID */ - ); - - if (markerName) { - console.timeEnd(markerName); - } - - wrapperInstance._renderedComponent._topLevelWrapper = wrapperInstance; - ReactMount._mountImageIntoNode(markup, container, wrapperInstance, shouldReuseMarkup, transaction); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode(componentInstance, container, shouldReuseMarkup, context) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled( - /* useCreateElement */ - !shouldReuseMarkup && ReactDOMFeatureFlags.useCreateElement); - transaction.perform(mountComponentIntoNode, null, componentInstance, container, transaction, shouldReuseMarkup, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ -function unmountComponentFromNode(instance, container, safely) { - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onBeginFlush(); - } - ReactReconciler.unmountComponent(instance, safely); - if (process.env.NODE_ENV !== 'production') { - ReactInstrumentation.debugTool.onEndFlush(); - } - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } -} - -/** - * True if the supplied DOM node has a direct React-rendered child that is - * not a React root element. Useful for warning in `render`, - * `unmountComponentAtNode`, etc. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM element contains a direct child that was - * rendered by React but is not a root element. - * @internal - */ -function hasNonRootReactChild(container) { - var rootEl = getReactRootElementInContainer(container); - if (rootEl) { - var inst = ReactDOMComponentTree.getInstanceFromNode(rootEl); - return !!(inst && inst._hostParent); - } -} - -/** - * True if the supplied DOM node is a React DOM element and - * it has been rendered by another copy of React. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM has been rendered by another copy of React - * @internal - */ -function nodeIsRenderedByOtherInstance(container) { - var rootEl = getReactRootElementInContainer(container); - return !!(rootEl && isReactNode(rootEl) && !ReactDOMComponentTree.getInstanceFromNode(rootEl)); -} - -/** - * True if the supplied DOM node is a valid node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid DOM node. - * @internal - */ -function isValidContainer(node) { - return !!(node && (node.nodeType === ELEMENT_NODE_TYPE || node.nodeType === DOC_NODE_TYPE || node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)); -} - -/** - * True if the supplied DOM node is a valid React node element. - * - * @param {?DOMElement} node The candidate DOM node. - * @return {boolean} True if the DOM is a valid React DOM node. - * @internal - */ -function isReactNode(node) { - return isValidContainer(node) && (node.hasAttribute(ROOT_ATTR_NAME) || node.hasAttribute(ATTR_NAME)); -} - -function getHostRootInstanceInContainer(container) { - var rootEl = getReactRootElementInContainer(container); - var prevHostInstance = rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl); - return prevHostInstance && !prevHostInstance._hostParent ? prevHostInstance : null; -} - -function getTopLevelWrapperInContainer(container) { - var root = getHostRootInstanceInContainer(container); - return root ? root._hostContainerInfo._topLevelWrapper : null; -} - -/** - * Temporary (?) hack so that we can store all top-level pending updates on - * composites instead of having to worry about different types of components - * here. - */ -var topLevelRootCounter = 1; -var TopLevelWrapper = function () { - this.rootID = topLevelRootCounter++; -}; -TopLevelWrapper.prototype.isReactComponent = {}; -if (process.env.NODE_ENV !== 'production') { - TopLevelWrapper.displayName = 'TopLevelWrapper'; -} -TopLevelWrapper.prototype.render = function () { - return this.props.child; -}; -TopLevelWrapper.isReactTopLevelWrapper = true; - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - * <div id="container"> <-- Supplied `container`. - * <div data-reactid=".3"> <-- Rendered reactRoot of React - * // ... component. - * </div> - * </div> - * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - TopLevelWrapper: TopLevelWrapper, - - /** - * Used by devtools. The keys are not important. - */ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function (container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function (prevComponent, nextElement, nextContext, container, callback) { - ReactMount.scrollMonitor(container, function () { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement, nextContext); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - return prevComponent; - }, - - /** - * Render a new component into the DOM. Hooked by hooks! - * - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - process.env.NODE_ENV !== 'production' ? 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') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : _prodInvariant('37') : void 0; - - 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; - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactComponent} parentComponent The conceptual parent of this render tree. - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - !(parentComponent != null && ReactInstanceMap.has(parentComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : _prodInvariant('38') : void 0; - return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback); - }, - - _renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { - ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render'); - !React.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, '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.' : '') : _prodInvariant('39', 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 />.' : nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : void 0; - - process.env.NODE_ENV !== 'production' ? 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.') : void 0; - - 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 (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? 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.') : void 0; - - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (internalGetID(rootElementSibling)) { - process.env.NODE_ENV !== 'production' ? 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.') : void 0; - break; - } - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild; - var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function (nextElement, container, callback) { - return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback); - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - 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.) - process.env.NODE_ENV !== 'production' ? 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') : void 0; - - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : _prodInvariant('40') : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? warning(!nodeIsRenderedByOtherInstance(container), "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0; - } - - 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 (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? 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.') : void 0; - } - - return false; - } - delete instancesByReactRootID[prevComponent._instance.rootID]; - ReactUpdates.batchedUpdates(unmountComponentFromNode, prevComponent, container, false); - return true; - }, - - _mountImageIntoNode: function (markup, container, instance, shouldReuseMarkup, transaction) { - !isValidContainer(container) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : _prodInvariant('41') : void 0; - - 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 (process.env.NODE_ENV !== 'production') { - // 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); - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, '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) : _prodInvariant('42', difference) : void 0; - - if (process.env.NODE_ENV !== 'production') { - process.env.NODE_ENV !== 'production' ? 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) : void 0; - } - } - } - - !(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, '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.') : _prodInvariant('43') : void 0; - - 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 (process.env.NODE_ENV !== 'production') { - var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild); - if (hostNode._debugID !== 0) { - ReactInstrumentation.debugTool.onHostOperation({ - instanceID: hostNode._debugID, - type: 'mount', - payload: markup.toString() - }); - } - } - } -}; - -module.exports = ReactMount;
\ No newline at end of file |