diff --git a/src/browser/__tests__/ReactDOM-test.js b/src/browser/__tests__/ReactDOM-test.js index b839089d2b..64328ee179 100644 --- a/src/browser/__tests__/ReactDOM-test.js +++ b/src/browser/__tests__/ReactDOM-test.js @@ -15,7 +15,6 @@ var React = require('React'); var ReactDOM = require('ReactDOM'); -var ReactMount = require('ReactMount'); var ReactTestUtils = require('ReactTestUtils'); var div = React.createFactory('div'); @@ -53,7 +52,7 @@ describe('ReactDOM', function() { var argDiv = ReactTestUtils.renderIntoDocument( div(null, 'child') ); - var argNode = ReactMount.getNode(argDiv._rootNodeID); + var argNode = argDiv.getDOMNode(); expect(argNode.innerHTML).toBe('child'); }); @@ -61,7 +60,7 @@ describe('ReactDOM', function() { var conflictDiv = ReactTestUtils.renderIntoDocument( div({children: 'fakechild'}, 'child') ); - var conflictNode = ReactMount.getNode(conflictDiv._rootNodeID); + var conflictNode = conflictDiv.getDOMNode(); expect(conflictNode.innerHTML).toBe('child'); }); @@ -103,7 +102,7 @@ describe('ReactDOM', function() { theBird:
} }); - var root = ReactMount.getNode(myDiv._rootNodeID); + var root = myDiv.getDOMNode(); var dog = root.childNodes[0]; expect(dog.className).toBe('bigdog'); }); diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index 3f57ec4f92..71f752e9e5 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -15,7 +15,6 @@ var CSSPropertyOperations = require('CSSPropertyOperations'); var DOMProperty = require('DOMProperty'); var DOMPropertyOperations = require('DOMPropertyOperations'); -var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin'); var ReactComponent = require('ReactComponent'); var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); var ReactMount = require('ReactMount'); @@ -148,7 +147,6 @@ function validateDangerousTag(tag) { function ReactDOMComponent(tag) { validateDangerousTag(tag); this._tag = tag; - this.tagName = tag.toUpperCase(); } ReactDOMComponent.displayName = 'ReactDOMComponent'; @@ -488,8 +486,7 @@ assign( ReactDOMComponent.prototype, ReactComponent.Mixin, ReactDOMComponent.Mixin, - ReactMultiChild.Mixin, - ReactBrowserComponentMixin + ReactMultiChild.Mixin ); module.exports = ReactDOMComponent; diff --git a/src/browser/ui/ReactMount.js b/src/browser/ui/ReactMount.js index 7124d59e3f..a6f7425654 100644 --- a/src/browser/ui/ReactMount.js +++ b/src/browser/ui/ReactMount.js @@ -135,13 +135,7 @@ function getNode(id) { * @internal */ function getNodeFromInstance(instance) { - // This instance can currently be either a public or private instance since - // native nodes are still public. - var id = instance._rootNodeID; - // TODO: Once these are only public instances, remove this conditional. - if (id == null) { - id = ReactInstanceMap.get(instance)._rootNodeID; - } + var id = ReactInstanceMap.get(instance)._rootNodeID; if (ReactEmptyComponent.isNullComponentID(id)) { return null; } diff --git a/src/browser/ui/dom/components/ReactDOMButton.js b/src/browser/ui/dom/components/ReactDOMButton.js index a5fd34caf6..79206afe9f 100644 --- a/src/browser/ui/dom/components/ReactDOMButton.js +++ b/src/browser/ui/dom/components/ReactDOMButton.js @@ -39,6 +39,7 @@ var mouseListenerNames = keyMirror({ */ var ReactDOMButton = ReactClass.createClass({ displayName: 'ReactDOMButton', + tagName: 'BUTTON', mixins: [AutoFocusMixin, ReactBrowserComponentMixin], diff --git a/src/browser/ui/dom/components/ReactDOMForm.js b/src/browser/ui/dom/components/ReactDOMForm.js index 8af4a2e7b1..20c2b038cc 100644 --- a/src/browser/ui/dom/components/ReactDOMForm.js +++ b/src/browser/ui/dom/components/ReactDOMForm.js @@ -27,6 +27,7 @@ var form = ReactElement.createFactory('form'); */ var ReactDOMForm = ReactClass.createClass({ displayName: 'ReactDOMForm', + tagName: 'FORM', mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin], diff --git a/src/browser/ui/dom/components/ReactDOMInput.js b/src/browser/ui/dom/components/ReactDOMInput.js index cf3758e55a..50026420a6 100644 --- a/src/browser/ui/dom/components/ReactDOMInput.js +++ b/src/browser/ui/dom/components/ReactDOMInput.js @@ -52,6 +52,7 @@ function forceUpdateIfMounted() { */ var ReactDOMInput = ReactClass.createClass({ displayName: 'ReactDOMInput', + tagName: 'INPUT', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], diff --git a/src/browser/ui/dom/components/ReactDOMOption.js b/src/browser/ui/dom/components/ReactDOMOption.js index 4faa788fb4..1657703e31 100644 --- a/src/browser/ui/dom/components/ReactDOMOption.js +++ b/src/browser/ui/dom/components/ReactDOMOption.js @@ -24,6 +24,7 @@ var option = ReactElement.createFactory('option'); */ var ReactDOMOption = ReactClass.createClass({ displayName: 'ReactDOMOption', + tagName: 'OPTION', mixins: [ReactBrowserComponentMixin], diff --git a/src/browser/ui/dom/components/ReactDOMSelect.js b/src/browser/ui/dom/components/ReactDOMSelect.js index 051a9759d6..e1ac3d68d9 100644 --- a/src/browser/ui/dom/components/ReactDOMSelect.js +++ b/src/browser/ui/dom/components/ReactDOMSelect.js @@ -109,6 +109,7 @@ function updateOptions(component, propValue) { */ var ReactDOMSelect = ReactClass.createClass({ displayName: 'ReactDOMSelect', + tagName: 'SELECT', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], diff --git a/src/browser/ui/dom/components/ReactDOMTextarea.js b/src/browser/ui/dom/components/ReactDOMTextarea.js index 765d023652..e0f7afee60 100644 --- a/src/browser/ui/dom/components/ReactDOMTextarea.js +++ b/src/browser/ui/dom/components/ReactDOMTextarea.js @@ -50,6 +50,7 @@ function forceUpdateIfMounted() { */ var ReactDOMTextarea = ReactClass.createClass({ displayName: 'ReactDOMTextarea', + tagName: 'TEXTAREA', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], diff --git a/src/core/ReactComponent.js b/src/core/ReactComponent.js index ffc8334408..564c7311cc 100644 --- a/src/core/ReactComponent.js +++ b/src/core/ReactComponent.js @@ -453,7 +453,11 @@ var ReactComponent = { * @internal */ getPublicInstance: function() { - return this; + invariant( + false, + 'getPublicInstance should never be called on the base class. It must ' + + 'be overriden.' + ); } } }; diff --git a/src/core/ReactNativeComponent.js b/src/core/ReactNativeComponent.js index 9f4be86474..3f03fa1c51 100644 --- a/src/core/ReactNativeComponent.js +++ b/src/core/ReactNativeComponent.js @@ -11,6 +11,9 @@ "use strict"; +var ReactClass = require('ReactClass'); +var ReactElement = require('ReactElement'); + var assign = require('Object.assign'); var invariant = require('invariant'); @@ -37,6 +40,22 @@ var ReactNativeComponentInjection = { } }; +function autoGenerateWrapperClass(type) { + return ReactClass.createClass({ + tagName: type.toUpperCase(), + render: function() { + return new ReactElement( + type, + null, + null, + null, + null, + this.props + ); + } + }); +} + /** * Create an internal class for a specific tag. * @@ -47,12 +66,7 @@ var ReactNativeComponentInjection = { function createInstanceForTag(tag, props, parentType) { var componentClass = tagToComponentClass[tag]; if (componentClass == null) { - invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - tag - ); - return new genericComponentClass(tag, props); + tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); } if (parentType === tag) { // Avoid recursion diff --git a/src/core/__tests__/ReactComponent-test.js b/src/core/__tests__/ReactComponent-test.js index 35e7ada062..3b09fb2f52 100644 --- a/src/core/__tests__/ReactComponent-test.js +++ b/src/core/__tests__/ReactComponent-test.js @@ -26,10 +26,6 @@ describe('ReactComponent', function() { reactComponentExpect = require('reactComponentExpect'); getMountDepth = function(instance) { - if (instance.mountComponent) { - // Native instance - return instance._mountDepth; - } return ReactInstanceMap.get(instance)._mountDepth; }; }); @@ -306,9 +302,9 @@ describe('ReactComponent', function() { expect(getMountDepth(root)).toBe(0); expect(getMountDepth(root.refs.switcher)).toBe(1); expect(getMountDepth(root.refs.switcher.refs.box)).toBe(2); - expect(getMountDepth(root.refs.switcher.refs.switcherDiv)).toBe(4); - expect(getMountDepth(root.refs.child)).toBe(5); + expect(getMountDepth(root.refs.switcher.refs.switcherDiv)).toBe(5); + expect(getMountDepth(root.refs.child)).toBe(7); expect(getMountDepth(root.refs.switcher.refs.box.refs.boxDiv)).toBe(3); - expect(getMountDepth(root.refs.child.refs.span)).toBe(6); + expect(getMountDepth(root.refs.child.refs.span)).toBe(8); }); }); diff --git a/src/core/__tests__/ReactCompositeComponent-test.js b/src/core/__tests__/ReactCompositeComponent-test.js index ef7f503a87..9c4a4c0722 100644 --- a/src/core/__tests__/ReactCompositeComponent-test.js +++ b/src/core/__tests__/ReactCompositeComponent-test.js @@ -66,8 +66,8 @@ describe('ReactCompositeComponent', function() { * reallocated again. */ ChildUpdates = React.createClass({ - getAnchorID: function() { - return this.refs.anch._rootNodeID; + getAnchor: function() { + return this.refs.anch; }, render: function() { var className = cx({'anchorClass': this.props.anchorClassOn}); @@ -182,8 +182,8 @@ describe('ReactCompositeComponent', function() { instance.setProps({renderAnchor: false}); // Clear out the anchor // rerender instance.setProps({renderAnchor: true, anchorClassOn: false}); - var anchorID = instance.getAnchorID(); - var actualDOMAnchorNode = ReactMount.getNode(anchorID); + var anchor = instance.getAnchor(); + var actualDOMAnchorNode = anchor.getDOMNode(); expect(actualDOMAnchorNode.className).toBe(''); }); @@ -779,9 +779,11 @@ describe('ReactCompositeComponent', function() { React.unmountComponentAtNode(container); expect(innerUnmounted).toBe(true); - //