aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react-dom/lib/ReactFiber.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/react-dom/lib/ReactFiber.js')
-rw-r--r--node_modules/react-dom/lib/ReactFiber.js190
1 files changed, 190 insertions, 0 deletions
diff --git a/node_modules/react-dom/lib/ReactFiber.js b/node_modules/react-dom/lib/ReactFiber.js
new file mode 100644
index 000000000..07737ecc4
--- /dev/null
+++ b/node_modules/react-dom/lib/ReactFiber.js
@@ -0,0 +1,190 @@
+/**
+ * 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 ReactTypeOfWork = require('./ReactTypeOfWork');
+var IndeterminateComponent = ReactTypeOfWork.IndeterminateComponent,
+ ClassComponent = ReactTypeOfWork.ClassComponent,
+ HostContainer = ReactTypeOfWork.HostContainer,
+ HostComponent = ReactTypeOfWork.HostComponent,
+ CoroutineComponent = ReactTypeOfWork.CoroutineComponent,
+ YieldComponent = ReactTypeOfWork.YieldComponent;
+
+var _require = require('./ReactPriorityLevel'),
+ NoWork = _require.NoWork;
+
+// An Instance is shared between all versions of a component. We can easily
+// break this out into a separate object to avoid copying so much to the
+// alternate versions of the tree. We put this on a single object for now to
+// minimize the number of objects created during the initial render.
+
+
+// A Fiber is work on a Component that needs to be done or was done. There can
+// be more than one per component.
+
+
+// This is a constructor of a POJO instead of a constructor function for a few
+// reasons:
+// 1) Nobody should add any instance methods on this. Instance methods can be
+// more difficult to predict when they get optimized and they are almost
+// never inlined properly in static compilers.
+// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
+// always know when it is a fiber.
+// 3) We can easily go from a createFiber call to calling a constructor if that
+// is faster. The opposite is not true.
+// 4) We might want to experiment with using numeric keys since they are easier
+// to optimize in a non-JIT environment.
+// 5) It should be easy to port this to a C struct and keep a C implementation
+// compatible.
+var createFiber = function (tag, key) {
+ return {
+
+ // Instance
+
+ tag: tag,
+
+ key: key,
+
+ type: null,
+
+ stateNode: null,
+
+ // Fiber
+
+ 'return': null,
+
+ child: null,
+ sibling: null,
+
+ ref: null,
+
+ pendingProps: null,
+ memoizedProps: null,
+ updateQueue: null,
+ memoizedState: null,
+ callbackList: null,
+ output: null,
+
+ nextEffect: null,
+ firstEffect: null,
+ lastEffect: null,
+
+ pendingWorkPriority: NoWork,
+ progressedPriority: NoWork,
+ progressedChild: null,
+
+ alternate: null
+
+ };
+};
+
+function shouldConstruct(Component) {
+ return !!(Component.prototype && Component.prototype.isReactComponent);
+}
+
+// This is used to create an alternate fiber to do work on.
+// TODO: Rename to createWorkInProgressFiber or something like that.
+exports.cloneFiber = function (fiber, priorityLevel) {
+ // We clone to get a work in progress. That means that this fiber is the
+ // current. To make it safe to reuse that fiber later on as work in progress
+ // we need to reset its work in progress flag now. We don't have an
+ // opportunity to do this earlier since we don't traverse the tree when
+ // the work in progress tree becomes the current tree.
+ // fiber.progressedPriority = NoWork;
+ // fiber.progressedChild = null;
+
+ // We use a double buffering pooling technique because we know that we'll only
+ // ever need at most two versions of a tree. We pool the "other" unused node
+ // that we're free to reuse. This is lazily created to avoid allocating extra
+ // objects for things that are never updated. It also allow us to reclaim the
+ // extra memory if needed.
+ var alt = fiber.alternate;
+ if (alt) {
+ // Whenever we clone, we do so to get a new work in progress.
+ // This ensures that we've reset these in the new tree.
+ alt.nextEffect = null;
+ alt.firstEffect = null;
+ alt.lastEffect = null;
+ } else {
+ // This should not have an alternate already
+ alt = createFiber(fiber.tag, fiber.key);
+ alt.type = fiber.type;
+
+ alt.progressedChild = fiber.progressedChild;
+ alt.progressedPriority = fiber.progressedPriority;
+
+ alt.alternate = fiber;
+ fiber.alternate = alt;
+ }
+
+ alt.stateNode = fiber.stateNode;
+ alt.child = fiber.child;
+ alt.sibling = fiber.sibling; // This should always be overridden. TODO: null
+ alt.ref = fiber.ref;
+ // pendingProps is here for symmetry but is unnecessary in practice for now.
+ // TODO: Pass in the new pendingProps as an argument maybe?
+ alt.pendingProps = fiber.pendingProps;
+ alt.updateQueue = fiber.updateQueue;
+ alt.callbackList = fiber.callbackList;
+ alt.pendingWorkPriority = priorityLevel;
+
+ alt.memoizedProps = fiber.memoizedProps;
+ alt.output = fiber.output;
+
+ return alt;
+};
+
+exports.createHostContainerFiber = function () {
+ var fiber = createFiber(HostContainer, null);
+ return fiber;
+};
+
+exports.createFiberFromElement = function (element, priorityLevel) {
+ // $FlowFixMe: ReactElement.key is currently defined as ?string but should be defined as null | string in Flow.
+ var fiber = createFiberFromElementType(element.type, element.key);
+ fiber.pendingProps = element.props;
+ fiber.pendingWorkPriority = priorityLevel;
+ return fiber;
+};
+
+function createFiberFromElementType(type, key) {
+ var fiber = void 0;
+ if (typeof type === 'function') {
+ fiber = shouldConstruct(type) ? createFiber(ClassComponent, key) : createFiber(IndeterminateComponent, key);
+ fiber.type = type;
+ } else if (typeof type === 'string') {
+ fiber = createFiber(HostComponent, key);
+ fiber.type = type;
+ } else if (typeof type === 'object' && type !== null) {
+ // Currently assumed to be a continuation and therefore is a fiber already.
+ fiber = type;
+ } else {
+ throw new Error('Unknown component type: ' + typeof type);
+ }
+ return fiber;
+}
+
+exports.createFiberFromElementType = createFiberFromElementType;
+
+exports.createFiberFromCoroutine = function (coroutine, priorityLevel) {
+ var fiber = createFiber(CoroutineComponent, coroutine.key);
+ fiber.type = coroutine.handler;
+ fiber.pendingProps = coroutine;
+ fiber.pendingWorkPriority = priorityLevel;
+ return fiber;
+};
+
+exports.createFiberFromYield = function (yieldNode, priorityLevel) {
+ var fiber = createFiber(YieldComponent, yieldNode.key);
+ fiber.pendingProps = {};
+ return fiber;
+}; \ No newline at end of file