Remove circular dependencies in React Core.

There is a circular dependency between `ReactID`, `ReactMount` and
`ReactInstanceHandles`. Ben and I talked about this today. It seems like the
simplest solution is to consolidate a lot of the code that Ben recently wrote
into `ReactMount`. We can later find ways to trim code out of this module
without causing circular deps.
This commit is contained in:
Jordan Walke
2013-07-24 17:40:57 -07:00
committed by Paul O’Shannessy
parent 260d90ba02
commit 2ee66262db
21 changed files with 356 additions and 367 deletions
+3 -3
View File
@@ -23,8 +23,8 @@
var getReactRootElementInContainer = require('getReactRootElementInContainer');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactDOMIDOperations = require('ReactDOMIDOperations');
var ReactID = require('ReactID');
var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactMount = require('ReactMount');
var ReactOwner = require('ReactOwner');
var ReactReconcileTransaction = require('ReactReconcileTransaction');
var ReactUpdates = require('ReactUpdates');
@@ -256,7 +256,7 @@ var ReactComponent = {
this.isMounted(),
'getDOMNode(): A component must be mounted to have a DOM node.'
);
return ReactID.getNode(this._rootNodeID);
return ReactMount.getNode(this._rootNodeID);
},
/**
@@ -382,7 +382,7 @@ var ReactComponent = {
if (props.ref != null) {
ReactOwner.removeComponentAsRefFrom(this, props.ref, props[OWNER]);
}
ReactID.purgeID(this._rootNodeID);
ReactMount.purgeID(this._rootNodeID);
this._rootNodeID = null;
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
},
+8 -8
View File
@@ -24,7 +24,7 @@
var CSSPropertyOperations = require('CSSPropertyOperations');
var DOMChildrenOperations = require('DOMChildrenOperations');
var DOMPropertyOperations = require('DOMPropertyOperations');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var getTextContentAccessor = require('getTextContentAccessor');
var invariant = require('invariant');
@@ -65,7 +65,7 @@ var ReactDOMIDOperations = {
* @internal
*/
updatePropertyByID: function(id, name, value) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
invariant(
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
'updatePropertyByID(...): %s',
@@ -91,7 +91,7 @@ var ReactDOMIDOperations = {
* @internal
*/
deletePropertyByID: function(id, name, value) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
invariant(
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
'updatePropertyByID(...): %s',
@@ -128,7 +128,7 @@ var ReactDOMIDOperations = {
* @internal
*/
updateStylesByID: function(id, styles) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
CSSPropertyOperations.setValueForStyles(node, styles);
},
@@ -140,7 +140,7 @@ var ReactDOMIDOperations = {
* @internal
*/
updateInnerHTMLByID: function(id, html) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
// HACK: IE8- normalize whitespace in innerHTML, removing leading spaces.
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
node.innerHTML = (html && html.__html || '').replace(/^ /g, ' ');
@@ -154,7 +154,7 @@ var ReactDOMIDOperations = {
* @internal
*/
updateTextContentByID: function(id, content) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
node[textContentAccessor] = content;
},
@@ -167,7 +167,7 @@ var ReactDOMIDOperations = {
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
*/
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
var node = ReactID.getNode(id);
var node = ReactMount.getNode(id);
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
},
@@ -176,7 +176,7 @@ var ReactDOMIDOperations = {
* Detect if any elements were removed instead of blindly purging.
*/
manageChildrenByParentID: function(parentID, domOperations) {
var parent = ReactID.getNode(parentID);
var parent = ReactMount.getNode(parentID);
DOMChildrenOperations.manageChildren(parent, domOperations);
}
+3
View File
@@ -24,6 +24,8 @@ var ReactDOMInput = require('ReactDOMInput');
var ReactDOMOption = require('ReactDOMOption');
var ReactDOMSelect = require('ReactDOMSelect');
var ReactDOMTextarea = require('ReactDOMTextarea');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactEventTopLevelCallback = require('ReactEventTopLevelCallback');
var DefaultDOMPropertyConfig = require('DefaultDOMPropertyConfig');
var DOMProperty = require('DOMProperty');
@@ -37,6 +39,7 @@ var SimpleEventPlugin = require('SimpleEventPlugin');
var MobileSafariClickEventPlugin = require('MobileSafariClickEventPlugin');
function inject() {
ReactEventEmitter.TopLevelCallbackCreator = ReactEventTopLevelCallback;
/**
* Inject module for resolving DOM hierarchy and plugin ordering.
*/
+6 -3
View File
@@ -257,17 +257,20 @@ var ReactEventEmitter = {
* reason, and only in some cases).
*
* @param {boolean} touchNotMouse Listen to touch events instead of mouse.
* @param {object} TopLevelCallbackCreator
*/
ensureListening: function(touchNotMouse, TopLevelCallbackCreator) {
ensureListening: function(touchNotMouse) {
invariant(
ExecutionEnvironment.canUseDOM,
'ensureListening(...): Cannot toggle event listening in a Worker ' +
'thread. This is likely a bug in the framework. Please report ' +
'immediately.'
);
invariant(
ReactEventEmitter.TopLevelCallbackCreator,
'ensureListening(...): Cannot be called without a top level callback ' +
'creator being injected.'
);
if (!_isListening) {
ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator;
listenAtTopLevel(touchNotMouse);
_isListening = true;
}
+4 -5
View File
@@ -21,8 +21,7 @@
var ExecutionEnvironment = require('ExecutionEnvironment');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactID = require('ReactID');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactMount = require('ReactMount');
var getEventTarget = require('getEventTarget');
@@ -34,7 +33,7 @@ var _topLevelListenersEnabled = true;
/**
* Top-level callback creator used to implement event handling using delegation.
* This is used via dependency injection in `ReactEventEmitter.ensureListening`.
* This is used via dependency injection.
*/
var ReactEventTopLevelCallback = {
@@ -73,10 +72,10 @@ var ReactEventTopLevelCallback = {
nativeEvent.srcElement !== nativeEvent.target) {
nativeEvent.target = nativeEvent.srcElement;
}
var topLevelTarget = ReactInstanceHandles.getFirstReactDOM(
var topLevelTarget = ReactMount.getFirstReactDOM(
getEventTarget(nativeEvent)
) || ExecutionEnvironment.global;
var topLevelTargetID = ReactID.getID(topLevelTarget) || '';
var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
ReactEventEmitter.handleTopLevel(
topLevelType,
topLevelTarget,
-163
View File
@@ -1,163 +0,0 @@
/**
* Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule ReactID
* @typechecks static-only
*/
"use strict";
var invariant = require('invariant');
var ReactMount = require('ReactMount');
var ATTR_NAME = 'data-reactid';
var nodeCache = {};
/**
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
* element can return its control whose name or ID equals ATTR_NAME. All
* DOM nodes support `getAttributeNode` but this can also get called on
* other objects so just return '' if we're given something other than a
* DOM node (such as window).
*
* @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
* @return {string} ID of the supplied `domNode`.
*/
function getID(node) {
var id = internalGetID(node);
if (id) {
if (nodeCache.hasOwnProperty(id)) {
var cached = nodeCache[id];
if (cached !== node) {
invariant(
!isValid(cached, id),
'ReactID: Two valid but unequal nodes with the same `%s`: %s',
ATTR_NAME, id
);
nodeCache[id] = node;
}
} else {
nodeCache[id] = node;
}
}
return id;
}
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 && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
}
/**
* Sets the React-specific ID of the given node.
*
* @param {DOMElement} node The DOM node whose ID will be set.
* @param {string} id The value of the ID attribute.
*/
function setID(node, id) {
var oldID = internalGetID(node);
if (oldID !== id) {
delete nodeCache[oldID];
}
node.setAttribute(ATTR_NAME, id);
nodeCache[id] = node;
}
/**
* Finds the node with the supplied React-generated DOM ID.
*
* @param {string} id A React-generated DOM ID.
* @return {DOMElement} DOM node with the suppled `id`.
* @internal
*/
function getNode(id) {
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
nodeCache[id] = ReactMount.findReactNodeByID(id);
}
return nodeCache[id];
}
/**
* A node is "valid" if it is contained by a currently mounted container.
*
* This means that the node does not have to be contained by a document in
* order to be considered valid.
*
* @param {?DOMElement} node The candidate DOM node.
* @param {string} id The expected ID of the node.
* @return {boolean} Whether the node is contained by a mounted container.
*/
function isValid(node, id) {
if (node) {
invariant(
internalGetID(node) === id,
'ReactID: Unexpected modification of `%s`',
ATTR_NAME
);
var container = ReactMount.findReactContainerForID(id);
if (container && contains(container, node)) {
return true;
}
}
return false;
}
function contains(ancestor, descendant) {
if (ancestor.contains) {
// Supported natively in virtually all browsers, but not in jsdom.
return ancestor.contains(descendant);
}
if (descendant === ancestor) {
return true;
}
if (descendant.nodeType === 3) {
// If descendant is a text node, start from descendant.parentNode
// instead, so that we can assume all ancestors worth considering are
// element nodes with nodeType === 1.
descendant = descendant.parentNode;
}
while (descendant && descendant.nodeType === 1) {
if (descendant === ancestor) {
return true;
}
descendant = descendant.parentNode;
}
return false;
}
/**
* Causes the cache to forget about one React-specific ID.
*
* @param {string} id The ID to forget.
*/
function purgeID(id) {
delete nodeCache[id];
}
exports.ATTR_NAME = ATTR_NAME;
exports.getID = getID;
exports.rawGetID = internalGetID;
exports.setID = setID;
exports.getNode = getNode;
exports.purgeID = purgeID;
+5 -100
View File
@@ -19,8 +19,6 @@
"use strict";
var ReactID = require('ReactID');
var invariant = require('invariant');
var SEPARATOR = '.';
@@ -239,103 +237,6 @@ var ReactInstanceHandles = {
);
},
/**
* True if the supplied `node` is rendered by React.
*
* @param {*} node DOM Element to check.
* @return {boolean} True if the DOM Element appears to be rendered by React.
* @internal
*/
isRenderedByReact: function(node) {
if (node.nodeType !== 1) {
// Not a DOMElement, therefore not a React component
return false;
}
var id = ReactID.getID(node);
return id ? id.charAt(0) === SEPARATOR : false;
},
/**
* Traverses up the ancestors of the supplied node to find a node that is a
* DOM representation of a React component.
*
* @param {*} node
* @return {?DOMEventTarget}
* @internal
*/
getFirstReactDOM: function(node) {
var current = node;
while (current && current.parentNode !== current) {
if (ReactInstanceHandles.isRenderedByReact(current)) {
return current;
}
current = current.parentNode;
}
return null;
},
/**
* Finds a node with the supplied `id` inside of the supplied `ancestorNode`.
* Exploits the ID naming scheme to perform the search quickly.
*
* @param {DOMEventTarget} ancestorNode Search from this root.
* @pararm {string} id ID of the DOM representation of the component.
* @return {DOMEventTarget} DOM node with the supplied `id`.
* @internal
*/
findComponentRoot: function(ancestorNode, id) {
var firstChildren = [ancestorNode.firstChild];
var childIndex = 0;
while (childIndex < firstChildren.length) {
var child = firstChildren[childIndex++];
while (child) {
var childID = ReactID.getID(child);
if (childID) {
if (id === childID) {
return child;
} else if (isAncestorIDOf(childID, id)) {
// If we find a child whose ID is an ancestor of the given ID,
// then we can be sure that we only want to search the subtree
// rooted at this child, so we can throw out the rest of the
// search state.
firstChildren.length = childIndex = 0;
firstChildren.push(child.firstChild);
break;
} else {
// TODO This should not be necessary if the ID hierarchy is
// correct, but is occasionally necessary if the DOM has been
// modified in unexpected ways.
firstChildren.push(child.firstChild);
}
} else {
// If this child had no ID, then there's a chance that it was
// injected automatically by the browser, as when a `<table>`
// element sprouts an extra `<tbody>` child as a side effect of
// `.innerHTML` parsing. Optimistically continue down this
// branch, but not before examining the other siblings.
firstChildren.push(child.firstChild);
}
child = child.nextSibling;
}
}
if (__DEV__) {
console.error(
'Error while invoking `findComponentRoot` with the following ' +
'ancestor node:',
ancestorNode
);
}
invariant(
false,
'findComponentRoot(..., %s): Unable to find element. This probably ' +
'means the DOM was unexpectedly mutated (e.g. by the browser).',
id,
ReactID.getID(ancestorNode)
);
},
/**
* Gets the DOM ID of the React component that is the root of the tree that
* contains the React component with the supplied DOM ID.
@@ -400,7 +301,11 @@ var ReactInstanceHandles = {
* Exposed for unit testing.
* @private
*/
_getNextDescendantID: getNextDescendantID
_getNextDescendantID: getNextDescendantID,
isAncestorIDOf: isAncestorIDOf,
SEPARATOR: SEPARATOR
};
+260 -17
View File
@@ -22,8 +22,11 @@ var invariant = require('invariant');
var getReactRootElementInContainer = require('getReactRootElementInContainer');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactEventTopLevelCallback = require('ReactEventTopLevelCallback');
var ReactID = require('ReactID');
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
var ATTR_NAME = 'data-reactid';
var nodeCache = {};
var $ = require('$');
@@ -44,7 +47,138 @@ if (__DEV__) {
*/
function getReactRootID(container) {
var rootElement = getReactRootElementInContainer(container);
return rootElement && ReactID.getID(rootElement);
return rootElement && ReactMount.getID(rootElement);
}
/**
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
* element can return its control whose name or ID equals ATTR_NAME. All
* DOM nodes support `getAttributeNode` but this can also get called on
* other objects so just return '' if we're given something other than a
* DOM node (such as window).
*
* @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
* @return {string} ID of the supplied `domNode`.
*/
function getID(node) {
var id = internalGetID(node);
if (id) {
if (nodeCache.hasOwnProperty(id)) {
var cached = nodeCache[id];
if (cached !== node) {
invariant(
!isValid(cached, id),
'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
ATTR_NAME, id
);
nodeCache[id] = node;
}
} else {
nodeCache[id] = node;
}
}
return id;
}
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 && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
}
/**
* Sets the React-specific ID of the given node.
*
* @param {DOMElement} node The DOM node whose ID will be set.
* @param {string} id The value of the ID attribute.
*/
function setID(node, id) {
var oldID = internalGetID(node);
if (oldID !== id) {
delete nodeCache[oldID];
}
node.setAttribute(ATTR_NAME, id);
nodeCache[id] = node;
}
/**
* Finds the node with the supplied React-generated DOM ID.
*
* @param {string} id A React-generated DOM ID.
* @return {DOMElement} DOM node with the suppled `id`.
* @internal
*/
function getNode(id) {
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
nodeCache[id] = ReactMount.findReactNodeByID(id);
}
return nodeCache[id];
}
/**
* A node is "valid" if it is contained by a currently mounted container.
*
* This means that the node does not have to be contained by a document in
* order to be considered valid.
*
* @param {?DOMElement} node The candidate DOM node.
* @param {string} id The expected ID of the node.
* @return {boolean} Whether the node is contained by a mounted container.
*/
function isValid(node, id) {
if (node) {
invariant(
internalGetID(node) === id,
'ReactMount: Unexpected modification of `%s`',
ATTR_NAME
);
var container = ReactMount.findReactContainerForID(id);
if (container && contains(container, node)) {
return true;
}
}
return false;
}
function contains(ancestor, descendant) {
if (ancestor.contains) {
// Supported natively in virtually all browsers, but not in jsdom.
return ancestor.contains(descendant);
}
if (descendant === ancestor) {
return true;
}
if (descendant.nodeType === 3) {
// If descendant is a text node, start from descendant.parentNode
// instead, so that we can assume all ancestors worth considering are
// element nodes with nodeType === 1.
descendant = descendant.parentNode;
}
while (descendant && descendant.nodeType === 1) {
if (descendant === ancestor) {
return true;
}
descendant = descendant.parentNode;
}
return false;
}
/**
* Causes the cache to forget about one React-specific ID.
*
* @param {string} id The ID to forget.
*/
function purgeID(id) {
delete nodeCache[id];
}
/**
@@ -89,14 +223,10 @@ var ReactMount = {
* Ensures that the top-level event delegation listener is set up. This will
* be invoked some time before the first time any React component is rendered.
*
* @param {object} TopLevelCallbackCreator
* @private
*/
prepareTopLevelEvents: function(TopLevelCallbackCreator) {
ReactEventEmitter.ensureListening(
ReactMount.useTouchEvents,
TopLevelCallbackCreator
);
prepareTopLevelEvents: function() {
ReactEventEmitter.ensureListening(ReactMount.useTouchEvents);
},
/**
@@ -132,7 +262,7 @@ var ReactMount = {
* @return {string} reactRoot ID prefix
*/
_registerComponent: function(nextComponent, container) {
ReactMount.prepareTopLevelEvents(ReactEventTopLevelCallback);
ReactMount.prepareTopLevelEvents();
var reactRootID = ReactMount.registerContainer(container);
instanceByReactRootID[reactRootID] = nextComponent;
@@ -196,8 +326,7 @@ var ReactMount = {
var reactRootElement = getReactRootElementInContainer(container);
var containerHasReactMarkup =
reactRootElement &&
ReactInstanceHandles.isRenderedByReact(reactRootElement);
reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
var shouldReuseMarkup = containerHasReactMarkup && !registeredComponent;
@@ -295,15 +424,15 @@ var ReactMount = {
var rootElement = rootElementsByReactRootID[reactRootID];
if (rootElement && rootElement.parentNode !== container) {
invariant(
// Call rawGetID here because getID calls isValid which calls
// Call internalGetID here because getID calls isValid which calls
// findReactContainerForID (this function).
ReactID.rawGetID(rootElement) === reactRootID,
internalGetID(rootElement) === reactRootID,
'ReactMount: Root element ID differed from reactRootID.'
);
var containerChild = container.firstChild;
if (containerChild &&
reactRootID === ReactID.rawGetID(containerChild)) {
reactRootID === internalGetID(containerChild)) {
// If the container has a new child with the same ID as the old
// root element, then rootElementsByReactRootID[reactRootID] is
// just stale and needs to be updated. The case that deserves a
@@ -329,8 +458,122 @@ var ReactMount = {
*/
findReactNodeByID: function(id) {
var reactRoot = ReactMount.findReactContainerForID(id);
return ReactInstanceHandles.findComponentRoot(reactRoot, id);
}
return ReactMount.findComponentRoot(reactRoot, id);
},
/**
* True if the supplied `node` is rendered by React.
*
* @param {*} node DOM Element to check.
* @return {boolean} True if the DOM Element appears to be rendered by React.
* @internal
*/
isRenderedByReact: function(node) {
if (node.nodeType !== 1) {
// Not a DOMElement, therefore not a React component
return false;
}
var id = ReactMount.getID(node);
return id ? id.charAt(0) === SEPARATOR : false;
},
/**
* Traverses up the ancestors of the supplied node to find a node that is a
* DOM representation of a React component.
*
* @param {*} node
* @return {?DOMEventTarget}
* @internal
*/
getFirstReactDOM: function(node) {
var current = node;
while (current && current.parentNode !== current) {
if (ReactMount.isRenderedByReact(current)) {
return current;
}
current = current.parentNode;
}
return null;
},
/**
* Finds a node with the supplied `id` inside of the supplied `ancestorNode`.
* Exploits the ID naming scheme to perform the search quickly.
*
* @param {DOMEventTarget} ancestorNode Search from this root.
* @pararm {string} id ID of the DOM representation of the component.
* @return {DOMEventTarget} DOM node with the supplied `id`.
* @internal
*/
findComponentRoot: function(ancestorNode, id) {
var firstChildren = [ancestorNode.firstChild];
var childIndex = 0;
while (childIndex < firstChildren.length) {
var child = firstChildren[childIndex++];
while (child) {
var childID = ReactMount.getID(child);
if (childID) {
if (id === childID) {
return child;
} else if (ReactInstanceHandles.isAncestorIDOf(childID, id)) {
// If we find a child whose ID is an ancestor of the given ID,
// then we can be sure that we only want to search the subtree
// rooted at this child, so we can throw out the rest of the
// search state.
firstChildren.length = childIndex = 0;
firstChildren.push(child.firstChild);
break;
} else {
// TODO This should not be necessary if the ID hierarchy is
// correct, but is occasionally necessary if the DOM has been
// modified in unexpected ways.
firstChildren.push(child.firstChild);
}
} else {
// If this child had no ID, then there's a chance that it was
// injected automatically by the browser, as when a `<table>`
// element sprouts an extra `<tbody>` child as a side effect of
// `.innerHTML` parsing. Optimistically continue down this
// branch, but not before examining the other siblings.
firstChildren.push(child.firstChild);
}
child = child.nextSibling;
}
}
if (__DEV__) {
console.error(
'Error while invoking `findComponentRoot` with the following ' +
'ancestor node:',
ancestorNode
);
}
invariant(
false,
'findComponentRoot(..., %s): Unable to find element. This probably ' +
'means the DOM was unexpectedly mutated (e.g. by the browser).',
id,
ReactMount.getID(ancestorNode)
);
},
/**
* React ID utilities.
*/
ATTR_NAME: ATTR_NAME,
getID: getID,
setID: setID,
getNode: getNode,
purgeID: purgeID,
injection: {}
};
module.exports = ReactMount;
+2 -2
View File
@@ -25,7 +25,7 @@ var DOMPropertyOperations = require('DOMPropertyOperations');
var ReactComponent = require('ReactComponent');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactMultiChild = require('ReactMultiChild');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var escapeTextForBrowser = require('escapeTextForBrowser');
var flattenChildren = require('flattenChildren');
@@ -136,7 +136,7 @@ ReactNativeComponent.Mixin = {
}
var escapedID = escapeTextForBrowser(this._rootNodeID);
return ret + ' ' + ReactID.ATTR_NAME + '="' + escapedID + '">';
return ret + ' ' + ReactMount.ATTR_NAME + '="' + escapedID + '">';
},
/**
+2 -2
View File
@@ -20,7 +20,7 @@
"use strict";
var ReactComponent = require('ReactComponent');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var escapeTextForBrowser = require('escapeTextForBrowser');
var mixInto = require('mixInto');
@@ -58,7 +58,7 @@ mixInto(ReactTextComponent, {
mountComponent: function(rootID) {
ReactComponent.Mixin.mountComponent.call(this, rootID);
return (
'<span ' + ReactID.ATTR_NAME + '="' + rootID + '">' +
'<span ' + ReactMount.ATTR_NAME + '="' + rootID + '">' +
escapeTextForBrowser(this.props.text) +
'</span>'
);
@@ -25,7 +25,7 @@ var React;
var ReactCurrentOwner;
var ReactPropTypes;
var ReactTestUtils;
var ReactID;
var ReactMount;
var ReactDoNotBindDeprecated;
var cx;
@@ -41,7 +41,7 @@ describe('ReactCompositeComponent', function() {
ReactDoNotBindDeprecated = require('ReactDoNotBindDeprecated');
ReactPropTypes = require('ReactPropTypes');
ReactTestUtils = require('ReactTestUtils');
ReactID = require('ReactID');
ReactMount = require('ReactMount');
MorphingComponent = React.createClass({
getInitialState: function() {
@@ -129,7 +129,7 @@ describe('ReactCompositeComponent', function() {
// rerender
instance.setProps({renderAnchor: true, anchorClassOn: false});
var anchorID = instance.getAnchorID();
var actualDOMAnchorNode = ReactID.getNode(anchorID);
var actualDOMAnchorNode = ReactMount.getNode(anchorID);
expect(actualDOMAnchorNode.className).toBe('');
});
+4 -4
View File
@@ -25,7 +25,7 @@ var React = require('React');
var ReactDOM = require('ReactDOM');
var ReactTestUtils = require('ReactTestUtils');
var React = require('React');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
describe('ref swapping', function() {
// TODO: uncomment this test once we can run in phantom, which
@@ -61,7 +61,7 @@ describe('ref swapping', function() {
var argDiv = ReactTestUtils.renderIntoDocument(
ReactDOM.div(null, 'child')
);
var argNode = ReactID.getNode(argDiv._rootNodeID);
var argNode = ReactMount.getNode(argDiv._rootNodeID);
expect(argNode.innerHTML).toBe('child');
});
@@ -69,7 +69,7 @@ describe('ref swapping', function() {
var conflictDiv = ReactTestUtils.renderIntoDocument(
ReactDOM.div({children: 'fakechild'}, 'child')
);
var conflictNode = ReactID.getNode(conflictDiv._rootNodeID);
var conflictNode = ReactMount.getNode(conflictDiv._rootNodeID);
expect(conflictNode.innerHTML).toBe('child');
});
@@ -111,7 +111,7 @@ describe('ref swapping', function() {
theBird: <div class="bird" />
}
});
var root = ReactID.getNode(myDiv._rootNodeID);
var root = ReactMount.getNode(myDiv._rootNodeID);
var dog = root.childNodes[0];
expect(dog.className).toBe('bigdog');
});
@@ -23,11 +23,11 @@
describe('ReactDOMIDOperations', function() {
var DOMPropertyOperations = require('DOMPropertyOperations');
var ReactDOMIDOperations = require('ReactDOMIDOperations');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var keyOf = require('keyOf');
it('should disallow updating special properties', function() {
spyOn(ReactID, "getNode");
spyOn(ReactMount, "getNode");
spyOn(DOMPropertyOperations, "setValueForProperty");
expect(function() {
@@ -39,7 +39,7 @@ describe('ReactDOMIDOperations', function() {
}).toThrow();
expect(
ReactID.getNode.argsForCall[0][0]
ReactMount.getNode.argsForCall[0][0]
).toBe('testID');
expect(
@@ -49,7 +49,7 @@ describe('ReactDOMIDOperations', function() {
it('should update innerHTML and special-case whitespace', function() {
var stubNode = document.createElement('div');
spyOn(ReactID, "getNode").andReturn(stubNode);
spyOn(ReactMount, "getNode").andReturn(stubNode);
ReactDOMIDOperations.updateInnerHTMLByID(
'testID',
@@ -57,7 +57,7 @@ describe('ReactDOMIDOperations', function() {
);
expect(
ReactID.getNode.argsForCall[0][0]
ReactMount.getNode.argsForCall[0][0]
).toBe('testID');
expect(stubNode.innerHTML).toBe('&nbsp;testContent');
+7 -7
View File
@@ -22,7 +22,7 @@ require('mock-modules')
.dontMock('BrowserScroll')
.dontMock('CallbackRegistry')
.dontMock('EventPluginHub')
.dontMock('ReactID')
.dontMock('ReactMount')
.dontMock('ReactEventEmitter')
.dontMock('ReactInstanceHandles')
.dontMock('EventPluginHub')
@@ -35,9 +35,9 @@ var keyOf = require('keyOf');
var mocks = require('mocks');
var EventPluginHub;
var ReactID = require('ReactID');
var getID = ReactID.getID;
var setID = ReactID.setID;
var ReactMount = require('ReactMount');
var getID = ReactMount.getID;
var setID = ReactMount.setID;
var ReactEventEmitter;
var ReactEventTopLevelCallback;
var ReactTestUtils;
@@ -89,9 +89,9 @@ describe('ReactEventEmitter', function() {
require('mock-modules').dumpCache();
EventPluginHub = require('EventPluginHub');
TapEventPlugin = require('TapEventPlugin');
ReactID = require('ReactID');
getID = ReactID.getID;
setID = ReactID.setID;
ReactMount = require('ReactMount');
getID = ReactMount.getID;
setID = ReactMount.setID;
ReactEventEmitter = require('ReactEventEmitter');
ReactTestUtils = require('ReactTestUtils');
ReactEventTopLevelCallback = require('ReactEventTopLevelCallback');
+5 -5
View File
@@ -22,7 +22,7 @@
var React;
var ReactTestUtils;
var reactComponentExpect;
var ReactID;
var ReactMount;
describe('ReactIdentity', function() {
@@ -31,12 +31,12 @@ describe('ReactIdentity', function() {
React = require('React');
ReactTestUtils = require('ReactTestUtils');
reactComponentExpect = require('reactComponentExpect');
ReactID = require('ReactID');
ReactMount = require('ReactMount');
});
var idExp = /^\.r\[.+?\](.*)$/;
function checkId(child, expectedId) {
var actual = idExp.exec(ReactID.getID(child));
var actual = idExp.exec(ReactMount.getID(child));
var expected = idExp.exec(expectedId);
expect(actual).toBeTruthy();
expect(expected).toBeTruthy();
@@ -281,11 +281,11 @@ describe('ReactIdentity', function() {
React.renderComponent(wrapped, document.createElement('div'));
var beforeID = ReactID.getID(wrapped.getDOMNode().firstChild);
var beforeID = ReactMount.getID(wrapped.getDOMNode().firstChild);
wrapped.swap();
var afterID = ReactID.getID(wrapped.getDOMNode().firstChild);
var afterID = ReactMount.getID(wrapped.getDOMNode().firstChild);
expect(beforeID).not.toEqual(afterID);
+17 -17
View File
@@ -21,7 +21,7 @@
var React = require('React');
var ReactTestUtils = require('ReactTestUtils');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
/**
* Ensure that all callbacks are invoked, passing this unique argument.
@@ -78,7 +78,7 @@ describe('ReactInstanceHandles', function() {
describe('isRenderedByReact', function() {
it('should not crash on text nodes', function() {
expect(function() {
ReactInstanceHandles.isRenderedByReact(document.createTextNode('yolo'));
ReactMount.isRenderedByReact(document.createTextNode('yolo'));
}).not.toThrow();
});
});
@@ -91,14 +91,14 @@ describe('ReactInstanceHandles', function() {
parentNode.appendChild(childNodeA);
parentNode.appendChild(childNodeB);
ReactID.setID(parentNode, '.react[0]');
ReactID.setID(childNodeA, '.react[0].0');
ReactID.setID(childNodeB, '.react[0].0:1');
ReactMount.setID(parentNode, '.react[0]');
ReactMount.setID(childNodeA, '.react[0].0');
ReactMount.setID(childNodeB, '.react[0].0:1');
expect(
ReactInstanceHandles.findComponentRoot(
ReactMount.findComponentRoot(
parentNode,
ReactID.getID(childNodeB)
ReactMount.getID(childNodeB)
)
).toBe(childNodeB);
});
@@ -110,14 +110,14 @@ describe('ReactInstanceHandles', function() {
parentNode.appendChild(childNodeA);
parentNode.appendChild(childNodeB);
ReactID.setID(parentNode, '.react[0]');
ReactMount.setID(parentNode, '.react[0]');
// No ID on `childNodeA`.
ReactID.setID(childNodeB, '.react[0].0:1');
ReactMount.setID(childNodeB, '.react[0].0:1');
expect(
ReactInstanceHandles.findComponentRoot(
ReactMount.findComponentRoot(
parentNode,
ReactID.getID(childNodeB)
ReactMount.getID(childNodeB)
)
).toBe(childNodeB);
});
@@ -129,22 +129,22 @@ describe('ReactInstanceHandles', function() {
parentNode.appendChild(childNodeA);
childNodeA.appendChild(childNodeB);
ReactID.setID(parentNode, '.react[0]');
ReactMount.setID(parentNode, '.react[0]');
// No ID on `childNodeA`, it was "rendered by the browser".
ReactID.setID(childNodeB, '.react[0].1:0');
ReactMount.setID(childNodeB, '.react[0].1:0');
expect(ReactInstanceHandles.findComponentRoot(
expect(ReactMount.findComponentRoot(
parentNode,
ReactID.getID(childNodeB)
ReactMount.getID(childNodeB)
)).toBe(childNodeB);
spyOn(console, 'error');
expect(console.error.argsForCall.length).toBe(0);
expect(function() {
ReactInstanceHandles.findComponentRoot(
ReactMount.findComponentRoot(
parentNode,
ReactID.getID(childNodeB) + ":junk"
ReactMount.getID(childNodeB) + ":junk"
);
}).toThrow(
'Invariant Violation: findComponentRoot(..., .react[0].1:0:junk): ' +
@@ -23,7 +23,7 @@ require('mock-modules');
var React = require('React');
var ReactTestUtils = require('ReactTestUtils');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var objMapKeyVal = require('objMapKeyVal');
@@ -191,7 +191,7 @@ function verifyDomOrderingAccurate(parentInstance, statusDisplays) {
var i;
var orderedDomIds = [];
for (i=0; i < statusDisplayNodes.length; i++) {
orderedDomIds.push(ReactID.getID(statusDisplayNodes[i]));
orderedDomIds.push(ReactMount.getID(statusDisplayNodes[i]));
}
var orderedLogicalIds = [];
@@ -317,7 +317,7 @@ describe('ReactNativeComponent', function() {
it("should clean up listeners", function() {
var React = require('React');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var container = document.createElement('div');
document.documentElement.appendChild(container);
@@ -327,7 +327,7 @@ describe('ReactNativeComponent', function() {
React.renderComponent(instance, container);
var rootNode = instance.getDOMNode();
var rootNodeID = ReactID.getID(rootNode);
var rootNodeID = ReactMount.getID(rootNode);
expect(
ReactEventEmitter.getListener(rootNodeID, 'onClick')
).toBe(callback);
@@ -24,7 +24,7 @@
require('mock-modules')
.dontMock('ExecutionEnvironment')
.dontMock('React')
.dontMock('ReactID')
.dontMock('ReactMount')
.dontMock('ReactServerRendering')
.dontMock('ReactTestUtils')
.dontMock('ReactMarkupChecksum');
@@ -32,7 +32,7 @@ require('mock-modules')
var mocks = require('mocks');
var React;
var ReactID;
var ReactMount;
var ReactTestUtils;
var ReactServerRendering;
var ReactMarkupChecksum;
@@ -42,7 +42,7 @@ describe('ReactServerRendering', function() {
beforeEach(function() {
require('mock-modules').dumpCache();
React = require('React');
ReactID = require('ReactID');
ReactMount = require('ReactMount');
ReactTestUtils = require('ReactTestUtils');
ExecutionEnvironment = require('ExecutionEnvironment');
ExecutionEnvironment.canUseDOM = false;
@@ -59,7 +59,7 @@ describe('ReactServerRendering', function() {
}
);
expect(response).toMatch(
'<span ' + ReactID.ATTR_NAME + '="[^"]+" ' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+" ' +
ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="[^"]+">hello world</span>'
);
});
@@ -83,11 +83,11 @@ describe('ReactServerRendering', function() {
}
);
expect(response).toMatch(
'<div ' + ReactID.ATTR_NAME + '="[^"]+" ' +
'<div ' + ReactMount.ATTR_NAME + '="[^"]+" ' +
ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="[^"]+">' +
'<span ' + ReactID.ATTR_NAME + '="[^"]+">' +
'<span ' + ReactID.ATTR_NAME + '="[^"]+">My name is </span>' +
'<span ' + ReactID.ATTR_NAME + '="[^"]+">child</span>' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+">' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+">My name is </span>' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+">child</span>' +
'</span>' +
'</div>'
);
@@ -137,10 +137,10 @@ describe('ReactServerRendering', function() {
);
expect(response).toMatch(
'<span ' + ReactID.ATTR_NAME + '="[^"]+" ' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+" ' +
ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="[^"]+">' +
'<span ' + ReactID.ATTR_NAME + '="[^"]+">Component name: </span>' +
'<span ' + ReactID.ATTR_NAME + '="[^"]+">TestComponent</span>' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+">Component name: </span>' +
'<span ' + ReactMount.ATTR_NAME + '="[^"]+">TestComponent</span>' +
'</span>'
);
expect(lifecycle).toEqual(
+4 -5
View File
@@ -22,14 +22,13 @@
var EventConstants = require('EventConstants');
var EventPropagators = require('EventPropagators');
var ExecutionEnvironment = require('ExecutionEnvironment');
var ReactInstanceHandles = require('ReactInstanceHandles');
var SyntheticMouseEvent = require('SyntheticMouseEvent');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var keyOf = require('keyOf');
var topLevelTypes = EventConstants.topLevelTypes;
var getFirstReactDOM = ReactInstanceHandles.getFirstReactDOM;
var getFirstReactDOM = ReactMount.getFirstReactDOM;
var eventTypes = {
mouseEnter: {registrationName: keyOf({onMouseEnter: null})},
@@ -85,8 +84,8 @@ var EnterLeaveEventPlugin = {
return null;
}
var fromID = from ? ReactID.getID(from) : '';
var toID = to ? ReactID.getID(to) : '';
var fromID = from ? ReactMount.getID(from) : '';
var toID = to ? ReactMount.getID(to) : '';
var leave = SyntheticMouseEvent.getPooled(
eventTypes.mouseLeave,
+3 -3
View File
@@ -21,7 +21,7 @@ var React = require('React');
var ReactComponent = require('ReactComponent');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactTextComponent = require('ReactTextComponent');
var ReactID = require('ReactID');
var ReactMount = require('ReactMount');
var mergeInto = require('mergeInto');
@@ -222,10 +222,10 @@ var ReactTestUtils = {
ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
topLevelType
);
var node = ReactID.getNode(reactRootID);
var node = ReactMount.getNode(reactRootID);
fakeNativeEvent.target = node;
/* jsdom is returning nodes without id's - fixing that issue here. */
ReactID.setID(node, reactRootID);
ReactMount.setID(node, reactRootID);
virtualHandler(fakeNativeEvent);
},