aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react-dom/lib/ReactChildReconciler.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/react-dom/lib/ReactChildReconciler.js')
-rw-r--r--node_modules/react-dom/lib/ReactChildReconciler.js153
1 files changed, 153 insertions, 0 deletions
diff --git a/node_modules/react-dom/lib/ReactChildReconciler.js b/node_modules/react-dom/lib/ReactChildReconciler.js
new file mode 100644
index 000000000..cf37bd63b
--- /dev/null
+++ b/node_modules/react-dom/lib/ReactChildReconciler.js
@@ -0,0 +1,153 @@
+/**
+ * Copyright 2014-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 ReactReconciler = require('./ReactReconciler');
+
+var instantiateReactComponent = require('./instantiateReactComponent');
+var KeyEscapeUtils = require('./KeyEscapeUtils');
+var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
+var traverseAllChildren = require('./traverseAllChildren');
+var warning = require('fbjs/lib/warning');
+
+var ReactComponentTreeHook;
+
+if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') {
+ // Temporary hack.
+ // Inline requires don't work well with Jest:
+ // https://github.com/facebook/react/issues/7240
+ // Remove the inline requires when we don't need them anymore:
+ // https://github.com/facebook/react/pull/7178
+ ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
+}
+
+function instantiateChild(childInstances, child, name, selfDebugID) {
+ // We found a component instance.
+ var keyUnique = childInstances[name] === undefined;
+ if (process.env.NODE_ENV !== 'production') {
+ if (!ReactComponentTreeHook) {
+ ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
+ }
+ if (!keyUnique) {
+ process.env.NODE_ENV !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0;
+ }
+ }
+ if (child != null && keyUnique) {
+ childInstances[name] = instantiateReactComponent(child, true);
+ }
+}
+
+/**
+ * ReactChildReconciler provides helpers for initializing or updating a set of
+ * children. Its output is suitable for passing it onto ReactMultiChild which
+ * does diffed reordering and insertion.
+ */
+var ReactChildReconciler = {
+ /**
+ * Generates a "mount image" for each of the supplied children. In the case
+ * of `ReactDOMComponent`, a mount image is a string of markup.
+ *
+ * @param {?object} nestedChildNodes Nested child maps.
+ * @return {?object} A set of child instances.
+ * @internal
+ */
+ instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID // 0 in production and for roots
+ ) {
+ if (nestedChildNodes == null) {
+ return null;
+ }
+ var childInstances = {};
+
+ if (process.env.NODE_ENV !== 'production') {
+ traverseAllChildren(nestedChildNodes, function (childInsts, child, name) {
+ return instantiateChild(childInsts, child, name, selfDebugID);
+ }, childInstances);
+ } else {
+ traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);
+ }
+ return childInstances;
+ },
+
+ /**
+ * Updates the rendered children and returns a new set of children.
+ *
+ * @param {?object} prevChildren Previously initialized set of children.
+ * @param {?object} nextChildren Flat child element maps.
+ * @param {ReactReconcileTransaction} transaction
+ * @param {object} context
+ * @return {?object} A new set of child instances.
+ * @internal
+ */
+ updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots
+ ) {
+ // We currently don't have a way to track moves here but if we use iterators
+ // instead of for..in we can zip the iterators and check if an item has
+ // moved.
+ // TODO: If nothing has changed, return the prevChildren object so that we
+ // can quickly bailout if nothing has changed.
+ if (!nextChildren && !prevChildren) {
+ return;
+ }
+ var name;
+ var prevChild;
+ for (name in nextChildren) {
+ if (!nextChildren.hasOwnProperty(name)) {
+ continue;
+ }
+ prevChild = prevChildren && prevChildren[name];
+ var prevElement = prevChild && prevChild._currentElement;
+ var nextElement = nextChildren[name];
+ if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {
+ ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);
+ nextChildren[name] = prevChild;
+ } else {
+ if (prevChild) {
+ removedNodes[name] = ReactReconciler.getHostNode(prevChild);
+ ReactReconciler.unmountComponent(prevChild, false);
+ }
+ // The child must be instantiated before it's mounted.
+ var nextChildInstance = instantiateReactComponent(nextElement, true);
+ nextChildren[name] = nextChildInstance;
+ // Creating mount image now ensures refs are resolved in right order
+ // (see https://github.com/facebook/react/pull/7101 for explanation).
+ var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID);
+ mountImages.push(nextChildMountImage);
+ }
+ }
+ // Unmount children that are no longer present.
+ for (name in prevChildren) {
+ if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
+ prevChild = prevChildren[name];
+ removedNodes[name] = ReactReconciler.getHostNode(prevChild);
+ ReactReconciler.unmountComponent(prevChild, false);
+ }
+ }
+ },
+
+ /**
+ * Unmounts all rendered children. This should be used to clean up children
+ * when this component is unmounted.
+ *
+ * @param {?object} renderedChildren Previously initialized set of children.
+ * @internal
+ */
+ unmountChildren: function (renderedChildren, safely) {
+ for (var name in renderedChildren) {
+ if (renderedChildren.hasOwnProperty(name)) {
+ var renderedChild = renderedChildren[name];
+ ReactReconciler.unmountComponent(renderedChild, safely);
+ }
+ }
+ }
+
+};
+
+module.exports = ReactChildReconciler; \ No newline at end of file