aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react-dom/lib/ReactFiberScheduler.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/react-dom/lib/ReactFiberScheduler.js')
-rw-r--r--node_modules/react-dom/lib/ReactFiberScheduler.js331
1 files changed, 0 insertions, 331 deletions
diff --git a/node_modules/react-dom/lib/ReactFiberScheduler.js b/node_modules/react-dom/lib/ReactFiberScheduler.js
deleted file mode 100644
index 0b1490608..000000000
--- a/node_modules/react-dom/lib/ReactFiberScheduler.js
+++ /dev/null
@@ -1,331 +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 ReactFiberBeginWork = require('./ReactFiberBeginWork');
-var ReactFiberCompleteWork = require('./ReactFiberCompleteWork');
-var ReactFiberCommitWork = require('./ReactFiberCommitWork');
-
-var _require = require('./ReactFiber'),
- cloneFiber = _require.cloneFiber;
-
-var _require2 = require('./ReactPriorityLevel'),
- NoWork = _require2.NoWork,
- LowPriority = _require2.LowPriority,
- AnimationPriority = _require2.AnimationPriority,
- SynchronousPriority = _require2.SynchronousPriority;
-
-var timeHeuristicForUnitOfWork = 1;
-
-module.exports = function (config) {
- // Use a closure to circumvent the circular dependency between the scheduler
- // and ReactFiberBeginWork. Don't know if there's a better way to do this.
- var scheduler = void 0;
- function getScheduler() {
- return scheduler;
- }
-
- var _ReactFiberBeginWork = ReactFiberBeginWork(config, getScheduler),
- beginWork = _ReactFiberBeginWork.beginWork;
-
- var _ReactFiberCompleteWo = ReactFiberCompleteWork(config),
- completeWork = _ReactFiberCompleteWo.completeWork;
-
- var _ReactFiberCommitWork = ReactFiberCommitWork(config),
- commitWork = _ReactFiberCommitWork.commitWork;
-
- var scheduleAnimationCallback = config.scheduleAnimationCallback;
- var scheduleDeferredCallback = config.scheduleDeferredCallback;
-
- // The default priority to use for updates.
- var defaultPriority = LowPriority;
-
- // The next work in progress fiber that we're currently working on.
- var nextUnitOfWork = null;
- var nextPriorityLevel = NoWork;
-
- // Linked list of roots with scheduled work on them.
- var nextScheduledRoot = null;
- var lastScheduledRoot = null;
-
- function findNextUnitOfWork() {
- // Clear out roots with no more work on them.
- while (nextScheduledRoot && nextScheduledRoot.current.pendingWorkPriority === NoWork) {
- nextScheduledRoot.isScheduled = false;
- if (nextScheduledRoot === lastScheduledRoot) {
- nextScheduledRoot = null;
- lastScheduledRoot = null;
- nextPriorityLevel = NoWork;
- return null;
- }
- nextScheduledRoot = nextScheduledRoot.nextScheduledRoot;
- }
- // TODO: This is scanning one root at a time. It should be scanning all
- // roots for high priority work before moving on to lower priorities.
- var root = nextScheduledRoot;
- var highestPriorityRoot = null;
- var highestPriorityLevel = NoWork;
- while (root) {
- if (highestPriorityLevel === NoWork || highestPriorityLevel > root.current.pendingWorkPriority) {
- highestPriorityLevel = root.current.pendingWorkPriority;
- highestPriorityRoot = root;
- }
- // We didn't find anything to do in this root, so let's try the next one.
- root = root.nextScheduledRoot;
- }
- if (highestPriorityRoot) {
- nextPriorityLevel = highestPriorityLevel;
- return cloneFiber(highestPriorityRoot.current, highestPriorityLevel);
- }
-
- nextPriorityLevel = NoWork;
- return null;
- }
-
- function commitAllWork(finishedWork) {
- // Commit all the side-effects within a tree.
- // TODO: Error handling.
- var effectfulFiber = finishedWork.firstEffect;
- while (effectfulFiber) {
- var current = effectfulFiber.alternate;
- commitWork(current, effectfulFiber);
- var next = effectfulFiber.nextEffect;
- // Ensure that we clean these up so that we don't accidentally keep them.
- // I'm not actually sure this matters because we can't reset firstEffect
- // and lastEffect since they're on every node, not just the effectful
- // ones. So we have to clean everything as we reuse nodes anyway.
- effectfulFiber.nextEffect = null;
- effectfulFiber = next;
- }
- }
-
- function resetWorkPriority(workInProgress) {
- var newPriority = NoWork;
- // progressedChild is going to be the child set with the highest priority.
- // Either it is the same as child, or it just bailed out because it choose
- // not to do the work.
- var child = workInProgress.progressedChild;
- while (child) {
- // Ensure that remaining work priority bubbles up.
- if (child.pendingWorkPriority !== NoWork && (newPriority === NoWork || newPriority > child.pendingWorkPriority)) {
- newPriority = child.pendingWorkPriority;
- }
- child = child.sibling;
- }
- workInProgress.pendingWorkPriority = newPriority;
- }
-
- function completeUnitOfWork(workInProgress) {
- while (true) {
- // The current, flushed, state of this fiber is the alternate.
- // Ideally nothing should rely on this, but relying on it here
- // means that we don't need an additional field on the work in
- // progress.
- var current = workInProgress.alternate;
- var next = completeWork(current, workInProgress);
-
- resetWorkPriority(workInProgress);
-
- // The work is now done. We don't need this anymore. This flags
- // to the system not to redo any work here.
- workInProgress.pendingProps = null;
- workInProgress.updateQueue = null;
-
- var returnFiber = workInProgress['return'];
-
- if (returnFiber) {
- // Ensure that the first and last effect of the parent corresponds
- // to the children's first and last effect. This probably relies on
- // children completing in order.
- if (!returnFiber.firstEffect) {
- returnFiber.firstEffect = workInProgress.firstEffect;
- }
- if (workInProgress.lastEffect) {
- if (returnFiber.lastEffect) {
- returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
- }
- returnFiber.lastEffect = workInProgress.lastEffect;
- }
- }
-
- if (next) {
- // If completing this work spawned new work, do that next.
- return next;
- } else if (workInProgress.sibling) {
- // If there is more work to do in this returnFiber, do that next.
- return workInProgress.sibling;
- } else if (returnFiber) {
- // If there's no more work in this returnFiber. Complete the returnFiber.
- workInProgress = returnFiber;
- continue;
- } else {
- // If we're at the root, there's no more work to do. We can flush it.
- var _root = workInProgress.stateNode;
- if (_root.current === workInProgress) {
- throw new Error('Cannot commit the same tree as before. This is probably a bug ' + 'related to the return field.');
- }
- _root.current = workInProgress;
- // TODO: We can be smarter here and only look for more work in the
- // "next" scheduled work since we've already scanned passed. That
- // also ensures that work scheduled during reconciliation gets deferred.
- // const hasMoreWork = workInProgress.pendingWorkPriority !== NoWork;
- commitAllWork(workInProgress);
- var nextWork = findNextUnitOfWork();
- // if (!nextWork && hasMoreWork) {
- // TODO: This can happen when some deep work completes and we don't
- // know if this was the last one. We should be able to keep track of
- // the highest priority still in the tree for one pass. But if we
- // terminate an update we don't know.
- // throw new Error('FiberRoots should not have flagged more work if there is none.');
- // }
- return nextWork;
- }
- }
- }
-
- function performUnitOfWork(workInProgress) {
- // The current, flushed, state of this fiber is the alternate.
- // Ideally nothing should rely on this, but relying on it here
- // means that we don't need an additional field on the work in
- // progress.
- var current = workInProgress.alternate;
- var next = beginWork(current, workInProgress, nextPriorityLevel);
-
- if (next) {
- // If this spawns new work, do that next.
- return next;
- } else {
- // Otherwise, complete the current work.
- return completeUnitOfWork(workInProgress);
- }
- }
-
- function performDeferredWork(deadline) {
- if (!nextUnitOfWork) {
- nextUnitOfWork = findNextUnitOfWork();
- }
- while (nextUnitOfWork) {
- if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
- nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
- if (!nextUnitOfWork) {
- // Find more work. We might have time to complete some more.
- nextUnitOfWork = findNextUnitOfWork();
- }
- } else {
- scheduleDeferredCallback(performDeferredWork);
- return;
- }
- }
- }
-
- function scheduleDeferredWork(root, priority) {
- // We must reset the current unit of work pointer so that we restart the
- // search from the root during the next tick, in case there is now higher
- // priority work somewhere earlier than before.
- if (priority <= nextPriorityLevel) {
- nextUnitOfWork = null;
- }
-
- // Set the priority on the root, without deprioritizing
- if (root.current.pendingWorkPriority === NoWork || priority <= root.current.pendingWorkPriority) {
- root.current.pendingWorkPriority = priority;
- }
-
- if (root.isScheduled) {
- // If we're already scheduled, we can bail out.
- return;
- }
- root.isScheduled = true;
- if (lastScheduledRoot) {
- // Schedule ourselves to the end.
- lastScheduledRoot.nextScheduledRoot = root;
- lastScheduledRoot = root;
- } else {
- // We're the only work scheduled.
- nextScheduledRoot = root;
- lastScheduledRoot = root;
- scheduleDeferredCallback(performDeferredWork);
- }
- }
-
- function performAnimationWork() {
- // Always start from the root
- nextUnitOfWork = findNextUnitOfWork();
- while (nextUnitOfWork && nextPriorityLevel !== NoWork) {
- nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
- if (!nextUnitOfWork) {
- // Keep searching for animation work until there's no more left
- nextUnitOfWork = findNextUnitOfWork();
- }
- // Stop if the next unit of work is low priority
- if (nextPriorityLevel > AnimationPriority) {
- scheduleDeferredCallback(performDeferredWork);
- return;
- }
- }
- }
-
- function scheduleAnimationWork(root, priorityLevel) {
- // Set the priority on the root, without deprioritizing
- if (root.current.pendingWorkPriority === NoWork || priorityLevel <= root.current.pendingWorkPriority) {
- root.current.pendingWorkPriority = priorityLevel;
- }
-
- if (root.isScheduled) {
- // If we're already scheduled, we can bail out.
- return;
- }
- root.isScheduled = true;
- if (lastScheduledRoot) {
- // Schedule ourselves to the end.
- lastScheduledRoot.nextScheduledRoot = root;
- lastScheduledRoot = root;
- } else {
- // We're the only work scheduled.
- nextScheduledRoot = root;
- lastScheduledRoot = root;
- scheduleAnimationCallback(performAnimationWork);
- }
- }
-
- function scheduleWork(root) {
- if (defaultPriority === SynchronousPriority) {
- throw new Error('Not implemented yet');
- }
-
- if (defaultPriority === NoWork) {
- return;
- }
- if (defaultPriority > AnimationPriority) {
- scheduleDeferredWork(root, defaultPriority);
- return;
- }
- scheduleAnimationWork(root, defaultPriority);
- }
-
- function performWithPriority(priorityLevel, fn) {
- var previousDefaultPriority = defaultPriority;
- defaultPriority = priorityLevel;
- try {
- fn();
- } finally {
- defaultPriority = previousDefaultPriority;
- }
- }
-
- scheduler = {
- scheduleWork: scheduleWork,
- scheduleDeferredWork: scheduleDeferredWork,
- performWithPriority: performWithPriority
- };
- return scheduler;
-}; \ No newline at end of file