aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react/lib/ReactComponentTreeHook.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-03 15:35:00 +0200
commitde98e0b232509d5f40c135d540a70e415272ff85 (patch)
treea79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/react/lib/ReactComponentTreeHook.js
parente0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff)
node_modules
Diffstat (limited to 'node_modules/react/lib/ReactComponentTreeHook.js')
-rw-r--r--node_modules/react/lib/ReactComponentTreeHook.js333
1 files changed, 333 insertions, 0 deletions
diff --git a/node_modules/react/lib/ReactComponentTreeHook.js b/node_modules/react/lib/ReactComponentTreeHook.js
new file mode 100644
index 000000000..b2faa205f
--- /dev/null
+++ b/node_modules/react/lib/ReactComponentTreeHook.js
@@ -0,0 +1,333 @@
+/**
+ * Copyright 2016-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 ReactCurrentOwner = require('./ReactCurrentOwner');
+
+var invariant = require('fbjs/lib/invariant');
+var warning = require('fbjs/lib/warning');
+
+function isNative(fn) {
+ // Based on isNative() from Lodash
+ var funcToString = Function.prototype.toString;
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var reIsNative = RegExp('^' + funcToString
+ // Take an example native function source for comparison
+ .call(hasOwnProperty)
+ // Strip regex characters so we can use it for regex
+ .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ // Remove hasOwnProperty from the template to make it generic
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
+ try {
+ var source = funcToString.call(fn);
+ return reIsNative.test(source);
+ } catch (err) {
+ return false;
+ }
+}
+
+var canUseCollections =
+// Array.from
+typeof Array.from === 'function' &&
+// Map
+typeof Map === 'function' && isNative(Map) &&
+// Map.prototype.keys
+Map.prototype != null && typeof Map.prototype.keys === 'function' && isNative(Map.prototype.keys) &&
+// Set
+typeof Set === 'function' && isNative(Set) &&
+// Set.prototype.keys
+Set.prototype != null && typeof Set.prototype.keys === 'function' && isNative(Set.prototype.keys);
+
+var setItem;
+var getItem;
+var removeItem;
+var getItemIDs;
+var addRoot;
+var removeRoot;
+var getRootIDs;
+
+if (canUseCollections) {
+ var itemMap = new Map();
+ var rootIDSet = new Set();
+
+ setItem = function (id, item) {
+ itemMap.set(id, item);
+ };
+ getItem = function (id) {
+ return itemMap.get(id);
+ };
+ removeItem = function (id) {
+ itemMap['delete'](id);
+ };
+ getItemIDs = function () {
+ return Array.from(itemMap.keys());
+ };
+
+ addRoot = function (id) {
+ rootIDSet.add(id);
+ };
+ removeRoot = function (id) {
+ rootIDSet['delete'](id);
+ };
+ getRootIDs = function () {
+ return Array.from(rootIDSet.keys());
+ };
+} else {
+ var itemByKey = {};
+ var rootByKey = {};
+
+ // Use non-numeric keys to prevent V8 performance issues:
+ // https://github.com/facebook/react/pull/7232
+ var getKeyFromID = function (id) {
+ return '.' + id;
+ };
+ var getIDFromKey = function (key) {
+ return parseInt(key.substr(1), 10);
+ };
+
+ setItem = function (id, item) {
+ var key = getKeyFromID(id);
+ itemByKey[key] = item;
+ };
+ getItem = function (id) {
+ var key = getKeyFromID(id);
+ return itemByKey[key];
+ };
+ removeItem = function (id) {
+ var key = getKeyFromID(id);
+ delete itemByKey[key];
+ };
+ getItemIDs = function () {
+ return Object.keys(itemByKey).map(getIDFromKey);
+ };
+
+ addRoot = function (id) {
+ var key = getKeyFromID(id);
+ rootByKey[key] = true;
+ };
+ removeRoot = function (id) {
+ var key = getKeyFromID(id);
+ delete rootByKey[key];
+ };
+ getRootIDs = function () {
+ return Object.keys(rootByKey).map(getIDFromKey);
+ };
+}
+
+var unmountedIDs = [];
+
+function purgeDeep(id) {
+ var item = getItem(id);
+ if (item) {
+ var childIDs = item.childIDs;
+
+ removeItem(id);
+ childIDs.forEach(purgeDeep);
+ }
+}
+
+function describeComponentFrame(name, source, ownerName) {
+ return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
+}
+
+function getDisplayName(element) {
+ if (element == null) {
+ return '#empty';
+ } else if (typeof element === 'string' || typeof element === 'number') {
+ return '#text';
+ } else if (typeof element.type === 'string') {
+ return element.type;
+ } else {
+ return element.type.displayName || element.type.name || 'Unknown';
+ }
+}
+
+function describeID(id) {
+ var name = ReactComponentTreeHook.getDisplayName(id);
+ var element = ReactComponentTreeHook.getElement(id);
+ var ownerID = ReactComponentTreeHook.getOwnerID(id);
+ var ownerName;
+ if (ownerID) {
+ ownerName = ReactComponentTreeHook.getDisplayName(ownerID);
+ }
+ process.env.NODE_ENV !== 'production' ? warning(element, 'ReactComponentTreeHook: Missing React element for debugID %s when ' + 'building stack', id) : void 0;
+ return describeComponentFrame(name, element && element._source, ownerName);
+}
+
+var ReactComponentTreeHook = {
+ onSetChildren: function (id, nextChildIDs) {
+ var item = getItem(id);
+ !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0;
+ item.childIDs = nextChildIDs;
+
+ for (var i = 0; i < nextChildIDs.length; i++) {
+ var nextChildID = nextChildIDs[i];
+ var nextChild = getItem(nextChildID);
+ !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected hook events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('140') : void 0;
+ !(nextChild.childIDs != null || typeof nextChild.element !== 'object' || nextChild.element == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() to fire for a container child before its parent includes it in onSetChildren().') : _prodInvariant('141') : void 0;
+ !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0;
+ if (nextChild.parentID == null) {
+ nextChild.parentID = id;
+ // TODO: This shouldn't be necessary but mounting a new root during in
+ // componentWillMount currently causes not-yet-mounted components to
+ // be purged from our tree data so their parent id is missing.
+ }
+ !(nextChild.parentID === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onBeforeMountComponent() parent and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('142', nextChildID, nextChild.parentID, id) : void 0;
+ }
+ },
+ onBeforeMountComponent: function (id, element, parentID) {
+ var item = {
+ element: element,
+ parentID: parentID,
+ text: null,
+ childIDs: [],
+ isMounted: false,
+ updateCount: 0
+ };
+ setItem(id, item);
+ },
+ onBeforeUpdateComponent: function (id, element) {
+ var item = getItem(id);
+ if (!item || !item.isMounted) {
+ // We may end up here as a result of setState() in componentWillUnmount().
+ // In this case, ignore the element.
+ return;
+ }
+ item.element = element;
+ },
+ onMountComponent: function (id) {
+ var item = getItem(id);
+ !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0;
+ item.isMounted = true;
+ var isRoot = item.parentID === 0;
+ if (isRoot) {
+ addRoot(id);
+ }
+ },
+ onUpdateComponent: function (id) {
+ var item = getItem(id);
+ if (!item || !item.isMounted) {
+ // We may end up here as a result of setState() in componentWillUnmount().
+ // In this case, ignore the element.
+ return;
+ }
+ item.updateCount++;
+ },
+ onUnmountComponent: function (id) {
+ var item = getItem(id);
+ if (item) {
+ // We need to check if it exists.
+ // `item` might not exist if it is inside an error boundary, and a sibling
+ // error boundary child threw while mounting. Then this instance never
+ // got a chance to mount, but it still gets an unmounting event during
+ // the error boundary cleanup.
+ item.isMounted = false;
+ var isRoot = item.parentID === 0;
+ if (isRoot) {
+ removeRoot(id);
+ }
+ }
+ unmountedIDs.push(id);
+ },
+ purgeUnmountedComponents: function () {
+ if (ReactComponentTreeHook._preventPurging) {
+ // Should only be used for testing.
+ return;
+ }
+
+ for (var i = 0; i < unmountedIDs.length; i++) {
+ var id = unmountedIDs[i];
+ purgeDeep(id);
+ }
+ unmountedIDs.length = 0;
+ },
+ isMounted: function (id) {
+ var item = getItem(id);
+ return item ? item.isMounted : false;
+ },
+ getCurrentStackAddendum: function (topElement) {
+ var info = '';
+ if (topElement) {
+ var name = getDisplayName(topElement);
+ var owner = topElement._owner;
+ info += describeComponentFrame(name, topElement._source, owner && owner.getName());
+ }
+
+ var currentOwner = ReactCurrentOwner.current;
+ var id = currentOwner && currentOwner._debugID;
+
+ info += ReactComponentTreeHook.getStackAddendumByID(id);
+ return info;
+ },
+ getStackAddendumByID: function (id) {
+ var info = '';
+ while (id) {
+ info += describeID(id);
+ id = ReactComponentTreeHook.getParentID(id);
+ }
+ return info;
+ },
+ getChildIDs: function (id) {
+ var item = getItem(id);
+ return item ? item.childIDs : [];
+ },
+ getDisplayName: function (id) {
+ var element = ReactComponentTreeHook.getElement(id);
+ if (!element) {
+ return null;
+ }
+ return getDisplayName(element);
+ },
+ getElement: function (id) {
+ var item = getItem(id);
+ return item ? item.element : null;
+ },
+ getOwnerID: function (id) {
+ var element = ReactComponentTreeHook.getElement(id);
+ if (!element || !element._owner) {
+ return null;
+ }
+ return element._owner._debugID;
+ },
+ getParentID: function (id) {
+ var item = getItem(id);
+ return item ? item.parentID : null;
+ },
+ getSource: function (id) {
+ var item = getItem(id);
+ var element = item ? item.element : null;
+ var source = element != null ? element._source : null;
+ return source;
+ },
+ getText: function (id) {
+ var element = ReactComponentTreeHook.getElement(id);
+ if (typeof element === 'string') {
+ return element;
+ } else if (typeof element === 'number') {
+ return '' + element;
+ } else {
+ return null;
+ }
+ },
+ getUpdateCount: function (id) {
+ var item = getItem(id);
+ return item ? item.updateCount : 0;
+ },
+
+
+ getRootIDs: getRootIDs,
+ getRegisteredIDs: getItemIDs
+};
+
+module.exports = ReactComponentTreeHook; \ No newline at end of file