mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #5014 from spicyj/native-parents
Thread native-parent pointers through everything
This commit is contained in:
commit
fb9e1ed475
18 files changed
+217
-132
No files matched your search
@@ -15,7 +15,7 @@ var ClientReactRootIndex = require('ClientReactRootIndex');
|
||||
var DOMProperty = require('DOMProperty');
|
||||
var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
|
||||
var ReactCurrentOwner = require('ReactCurrentOwner');
|
||||
var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
|
||||
var ReactDOMContainerInfo = require('ReactDOMContainerInfo');
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactEmptyComponentRegistry = require('ReactEmptyComponentRegistry');
|
||||
var ReactInstanceHandles = require('ReactInstanceHandles');
|
||||
@@ -26,14 +26,12 @@ var ReactReconciler = require('ReactReconciler');
|
||||
var ReactUpdateQueue = require('ReactUpdateQueue');
|
||||
var ReactUpdates = require('ReactUpdates');
|
||||
|
||||
var assign = require('Object.assign');
|
||||
var emptyObject = require('emptyObject');
|
||||
var containsNode = require('containsNode');
|
||||
var instantiateReactComponent = require('instantiateReactComponent');
|
||||
var invariant = require('invariant');
|
||||
var setInnerHTML = require('setInnerHTML');
|
||||
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
|
||||
var validateDOMNesting = require('validateDOMNesting');
|
||||
var warning = require('warning');
|
||||
|
||||
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
|
||||
@@ -43,9 +41,6 @@ var ELEMENT_NODE_TYPE = 1;
|
||||
var DOC_NODE_TYPE = 9;
|
||||
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;
|
||||
|
||||
var ownerDocumentContextKey =
|
||||
'__ReactMount_ownerDocument$' + Math.random().toString(36).slice(2);
|
||||
|
||||
|
||||
/** Mapping from reactRootID to React component instance. */
|
||||
var instancesByReactRootID = {};
|
||||
@@ -279,24 +274,13 @@ function mountComponentIntoNode(
|
||||
shouldReuseMarkup,
|
||||
context
|
||||
) {
|
||||
if (ReactDOMFeatureFlags.useCreateElement) {
|
||||
context = assign({}, context);
|
||||
if (container.nodeType === DOC_NODE_TYPE) {
|
||||
context[ownerDocumentContextKey] = container;
|
||||
} else {
|
||||
context[ownerDocumentContextKey] = container.ownerDocument;
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (context === emptyObject) {
|
||||
context = {};
|
||||
}
|
||||
var tag = container.nodeName.toLowerCase();
|
||||
context[validateDOMNesting.ancestorInfoContextKey] =
|
||||
validateDOMNesting.updatedAncestorInfo(null, tag, null);
|
||||
}
|
||||
var markup = ReactReconciler.mountComponent(
|
||||
componentInstance, rootID, transaction, context
|
||||
componentInstance,
|
||||
rootID,
|
||||
transaction,
|
||||
null,
|
||||
ReactDOMContainerInfo(container),
|
||||
context
|
||||
);
|
||||
componentInstance._renderedComponent._topLevelWrapper = componentInstance;
|
||||
ReactMount._mountImageIntoNode(
|
||||
@@ -1081,8 +1065,6 @@ var ReactMount = {
|
||||
}
|
||||
},
|
||||
|
||||
ownerDocumentContextKey: ownerDocumentContextKey,
|
||||
|
||||
/**
|
||||
* React ID utilities.
|
||||
*/
|
||||
|
||||
@@ -412,9 +412,6 @@ if (__DEV__) {
|
||||
}
|
||||
};
|
||||
|
||||
validateDOMNesting.ancestorInfoContextKey =
|
||||
'__validateDOMNesting_ancestorInfo$' + Math.random().toString(36).slice(2);
|
||||
|
||||
validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;
|
||||
|
||||
// For testing
|
||||
|
||||
@@ -30,7 +30,7 @@ var mouseListenerNames = {
|
||||
* when `disabled` is set.
|
||||
*/
|
||||
var ReactDOMButton = {
|
||||
getNativeProps: function(inst, props, context) {
|
||||
getNativeProps: function(inst, props) {
|
||||
if (!props.disabled) {
|
||||
return props;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ function forceUpdateIfMounted() {
|
||||
* @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
|
||||
*/
|
||||
var ReactDOMInput = {
|
||||
getNativeProps: function(inst, props, context) {
|
||||
getNativeProps: function(inst, props) {
|
||||
var value = LinkedValueUtils.getValue(props);
|
||||
var checked = LinkedValueUtils.getChecked(props);
|
||||
|
||||
|
||||
@@ -17,13 +17,11 @@ var ReactDOMSelect = require('ReactDOMSelect');
|
||||
var assign = require('Object.assign');
|
||||
var warning = require('warning');
|
||||
|
||||
var valueContextKey = ReactDOMSelect.valueContextKey;
|
||||
|
||||
/**
|
||||
* Implements an <option> native component that warns when `selected` is set.
|
||||
*/
|
||||
var ReactDOMOption = {
|
||||
mountWrapper: function(inst, props, context) {
|
||||
mountWrapper: function(inst, props, nativeParent) {
|
||||
// TODO (yungsters): Remove support for `selected` in <option>.
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
@@ -33,10 +31,13 @@ var ReactDOMOption = {
|
||||
);
|
||||
}
|
||||
|
||||
// Look up whether this option is 'selected' via context
|
||||
var selectValue = context[valueContextKey];
|
||||
// Look up whether this option is 'selected'
|
||||
var selectValue = null;
|
||||
if (nativeParent != null && nativeParent._tag === 'select') {
|
||||
selectValue = ReactDOMSelect.getSelectValueContext(nativeParent);
|
||||
}
|
||||
|
||||
// If context key is null (e.g., no specified value or after initial mount)
|
||||
// If the value is null (e.g., no specified value or after initial mount)
|
||||
// or missing (e.g., for <datalist>), we don't change props.selected
|
||||
var selected = null;
|
||||
if (selectValue != null) {
|
||||
@@ -57,7 +58,7 @@ var ReactDOMOption = {
|
||||
inst._wrapperState = {selected: selected};
|
||||
},
|
||||
|
||||
getNativeProps: function(inst, props, context) {
|
||||
getNativeProps: function(inst, props) {
|
||||
var nativeProps = assign({selected: undefined, children: undefined}, props);
|
||||
|
||||
// Read state only from initial mount because <select> updates value
|
||||
|
||||
@@ -20,9 +20,6 @@ var warning = require('warning');
|
||||
|
||||
var didWarnValueLink = false;
|
||||
|
||||
var valueContextKey =
|
||||
'__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);
|
||||
|
||||
function updateOptionsIfPendingUpdateAndMounted() {
|
||||
if (this._rootNodeID && this._wrapperState.pendingUpdate) {
|
||||
this._wrapperState.pendingUpdate = false;
|
||||
@@ -146,9 +143,7 @@ function updateOptions(inst, multiple, propValue) {
|
||||
* selected.
|
||||
*/
|
||||
var ReactDOMSelect = {
|
||||
valueContextKey: valueContextKey,
|
||||
|
||||
getNativeProps: function(inst, props, context) {
|
||||
getNativeProps: function(inst, props) {
|
||||
return assign({}, props, {
|
||||
onChange: inst._wrapperState.onChange,
|
||||
value: undefined,
|
||||
@@ -169,19 +164,17 @@ var ReactDOMSelect = {
|
||||
};
|
||||
},
|
||||
|
||||
processChildContext: function(inst, props, context) {
|
||||
// Pass down initial value so initial generated markup has correct
|
||||
// `selected` attributes
|
||||
var childContext = assign({}, context);
|
||||
childContext[valueContextKey] = inst._wrapperState.initialValue;
|
||||
return childContext;
|
||||
getSelectValueContext: function(inst) {
|
||||
// ReactDOMOption looks at this initial value so the initial generated
|
||||
// markup has correct `selected` attributes
|
||||
return inst._wrapperState.initialValue;
|
||||
},
|
||||
|
||||
postUpdateWrapper: function(inst) {
|
||||
var props = inst._currentElement.props;
|
||||
|
||||
// After the initial mount, we control selected-ness manually so don't pass
|
||||
// the context value down
|
||||
// this value down
|
||||
inst._wrapperState.initialValue = undefined;
|
||||
|
||||
var wasMultiple = inst._wrapperState.wasMultiple;
|
||||
|
||||
@@ -44,7 +44,7 @@ function forceUpdateIfMounted() {
|
||||
* `defaultValue` if specified, or the children content (deprecated).
|
||||
*/
|
||||
var ReactDOMTextarea = {
|
||||
getNativeProps: function(inst, props, context) {
|
||||
getNativeProps: function(inst, props) {
|
||||
invariant(
|
||||
props.dangerouslySetInnerHTML == null,
|
||||
'`dangerouslySetInnerHTML` does not make sense on <textarea>.'
|
||||
|
||||
@@ -46,8 +46,13 @@ function renderToStringImpl(element, makeStaticMarkup) {
|
||||
|
||||
return transaction.perform(function() {
|
||||
var componentInstance = instantiateReactComponent(element, null);
|
||||
var markup =
|
||||
componentInstance.mountComponent(id, transaction, emptyObject);
|
||||
var markup = componentInstance.mountComponent(
|
||||
id,
|
||||
transaction,
|
||||
null,
|
||||
null,
|
||||
emptyObject
|
||||
);
|
||||
if (!makeStaticMarkup) {
|
||||
markup = ReactMarkupChecksum.addChecksumToMarkup(markup);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright 2013-2015, 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.
|
||||
*
|
||||
* @providesModule DOMNamespaces
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var DOMNamespaces = {
|
||||
html: 'http://www.w3.org/1999/xhtml',
|
||||
mathml: 'http://www.w3.org/1998/Math/MathML',
|
||||
svg: 'http://www.w3.org/2000/svg',
|
||||
};
|
||||
|
||||
module.exports = DOMNamespaces;
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
var AutoFocusUtils = require('AutoFocusUtils');
|
||||
var CSSPropertyOperations = require('CSSPropertyOperations');
|
||||
var DOMNamespaces = require('DOMNamespaces');
|
||||
var DOMProperty = require('DOMProperty');
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var EventConstants = require('EventConstants');
|
||||
@@ -474,15 +475,6 @@ function validateDangerousTag(tag) {
|
||||
}
|
||||
}
|
||||
|
||||
function processChildContextDev(context, inst) {
|
||||
// Pass down our tag name to child components for validation purposes
|
||||
context = assign({}, context);
|
||||
var info = context[validateDOMNesting.ancestorInfoContextKey];
|
||||
context[validateDOMNesting.ancestorInfoContextKey] =
|
||||
validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst);
|
||||
return context;
|
||||
}
|
||||
|
||||
function isCustomComponent(tagName, props) {
|
||||
return tagName.indexOf('-') >= 0 || props.is != null;
|
||||
}
|
||||
@@ -512,17 +504,18 @@ function getNode(inst) {
|
||||
function ReactDOMComponent(tag) {
|
||||
validateDangerousTag(tag);
|
||||
this._tag = tag.toLowerCase();
|
||||
this._namespaceURI = null;
|
||||
this._renderedChildren = null;
|
||||
this._previousStyle = null;
|
||||
this._previousStyleCopy = null;
|
||||
this._nativeNode = null;
|
||||
this._rootNodeID = null;
|
||||
this._nativeContainerInfo = null;
|
||||
this._wrapperState = null;
|
||||
this._topLevelWrapper = null;
|
||||
this._nodeHasLegacyProperties = false;
|
||||
if (__DEV__) {
|
||||
this._unprocessedContextDev = null;
|
||||
this._processedContextDev = null;
|
||||
this._ancestorInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,11 +534,20 @@ ReactDOMComponent.Mixin = {
|
||||
* @internal
|
||||
* @param {string} rootID The root DOM ID for this node.
|
||||
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
||||
* @param {?ReactDOMComponent} the containing DOM component instance
|
||||
* @param {?object} info about the native container
|
||||
* @param {object} context
|
||||
* @return {string} The computed markup.
|
||||
*/
|
||||
mountComponent: function(rootID, transaction, context) {
|
||||
mountComponent: function(
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
) {
|
||||
this._rootNodeID = rootID;
|
||||
this._nativeContainerInfo = nativeContainerInfo;
|
||||
|
||||
var props = this._currentElement.props;
|
||||
|
||||
@@ -561,48 +563,80 @@ ReactDOMComponent.Mixin = {
|
||||
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
||||
break;
|
||||
case 'button':
|
||||
props = ReactDOMButton.getNativeProps(this, props, context);
|
||||
props = ReactDOMButton.getNativeProps(this, props, nativeParent);
|
||||
break;
|
||||
case 'input':
|
||||
ReactDOMInput.mountWrapper(this, props, context);
|
||||
props = ReactDOMInput.getNativeProps(this, props, context);
|
||||
ReactDOMInput.mountWrapper(this, props, nativeParent);
|
||||
props = ReactDOMInput.getNativeProps(this, props);
|
||||
break;
|
||||
case 'option':
|
||||
ReactDOMOption.mountWrapper(this, props, context);
|
||||
props = ReactDOMOption.getNativeProps(this, props, context);
|
||||
ReactDOMOption.mountWrapper(this, props, nativeParent);
|
||||
props = ReactDOMOption.getNativeProps(this, props);
|
||||
break;
|
||||
case 'select':
|
||||
ReactDOMSelect.mountWrapper(this, props, context);
|
||||
props = ReactDOMSelect.getNativeProps(this, props, context);
|
||||
context = ReactDOMSelect.processChildContext(this, props, context);
|
||||
ReactDOMSelect.mountWrapper(this, props, nativeParent);
|
||||
props = ReactDOMSelect.getNativeProps(this, props);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.mountWrapper(this, props, context);
|
||||
props = ReactDOMTextarea.getNativeProps(this, props, context);
|
||||
ReactDOMTextarea.mountWrapper(this, props, nativeParent);
|
||||
props = ReactDOMTextarea.getNativeProps(this, props);
|
||||
break;
|
||||
}
|
||||
|
||||
assertValidProps(this, props);
|
||||
if (__DEV__) {
|
||||
if (context[validateDOMNesting.ancestorInfoContextKey]) {
|
||||
validateDOMNesting(
|
||||
this._tag,
|
||||
this,
|
||||
context[validateDOMNesting.ancestorInfoContextKey]
|
||||
);
|
||||
|
||||
// We create tags in the namespace of their parent container, except HTML
|
||||
// tags get no namespace.
|
||||
var namespaceURI;
|
||||
var parentTag;
|
||||
if (nativeParent != null) {
|
||||
namespaceURI = nativeParent._namespaceURI;
|
||||
parentTag = nativeParent._tag;
|
||||
} else if (nativeContainerInfo != null) {
|
||||
namespaceURI = nativeContainerInfo._namespaceURI;
|
||||
parentTag = nativeContainerInfo._tag;
|
||||
}
|
||||
if (namespaceURI == null ||
|
||||
namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') {
|
||||
namespaceURI = DOMNamespaces.html;
|
||||
}
|
||||
if (namespaceURI === DOMNamespaces.html) {
|
||||
if (this._tag === 'svg') {
|
||||
namespaceURI = DOMNamespaces.svg;
|
||||
} else if (this._tag === 'math') {
|
||||
namespaceURI = DOMNamespaces.mathml;
|
||||
}
|
||||
}
|
||||
this._namespaceURI = namespaceURI;
|
||||
|
||||
if (__DEV__) {
|
||||
this._unprocessedContextDev = context;
|
||||
this._processedContextDev = processChildContextDev(context, this);
|
||||
context = this._processedContextDev;
|
||||
var parentInfo;
|
||||
if (nativeParent != null) {
|
||||
parentInfo = nativeParent._ancestorInfo;
|
||||
} else if (nativeContainerInfo != null) {
|
||||
parentInfo = nativeContainerInfo._ancestorInfo;
|
||||
}
|
||||
if (parentInfo) {
|
||||
// parentInfo should always be present except for the top-level
|
||||
// component when server rendering
|
||||
validateDOMNesting(this._tag, this, parentInfo);
|
||||
}
|
||||
this._ancestorInfo =
|
||||
validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this);
|
||||
}
|
||||
|
||||
var mountImage;
|
||||
if (transaction.useCreateElement) {
|
||||
var ownerDocument = context[ReactMount.ownerDocumentContextKey];
|
||||
var el = ownerDocument.createElement(this._currentElement.type);
|
||||
var ownerDocument = nativeContainerInfo._ownerDocument;
|
||||
var el;
|
||||
if (namespaceURI === DOMNamespaces.html) {
|
||||
el = ownerDocument.createElement(this._currentElement.type);
|
||||
} else {
|
||||
el = ownerDocument.createElementNS(
|
||||
namespaceURI,
|
||||
this._currentElement.type
|
||||
);
|
||||
}
|
||||
this._nativeNode = el;
|
||||
DOMPropertyOperations.setAttributeForID(el, this._rootNodeID);
|
||||
// Populate node cache
|
||||
@@ -835,18 +869,6 @@ ReactDOMComponent.Mixin = {
|
||||
break;
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
// If the context is reference-equal to the old one, pass down the same
|
||||
// processed object so the update bailout in ReactReconciler behaves
|
||||
// correctly (and identically in dev and prod). See #5005.
|
||||
if (this._unprocessedContextDev !== context) {
|
||||
this._unprocessedContextDev = context;
|
||||
this._processedContextDev = processChildContextDev(context, this);
|
||||
}
|
||||
context = this._processedContextDev;
|
||||
}
|
||||
|
||||
|
||||
assertValidProps(this, nextProps);
|
||||
this._updateDOMProperties(lastProps, nextProps, transaction);
|
||||
this._updateDOMChildren(
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright 2013-2015, 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.
|
||||
*
|
||||
* @providesModule ReactDOMContainerInfo
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var validateDOMNesting = require('validateDOMNesting');
|
||||
|
||||
var DOC_NODE_TYPE = 9;
|
||||
|
||||
function ReactDOMContainerInfo(node) {
|
||||
var info = {
|
||||
_ownerDocument: node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument,
|
||||
_tag: node.nodeName.toLowerCase(),
|
||||
_namespaceURI: node.namespaceURI,
|
||||
};
|
||||
if (__DEV__) {
|
||||
info._ancestorInfo =
|
||||
validateDOMNesting.updatedAncestorInfo(null, info._tag, null);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
module.exports = ReactDOMContainerInfo;
|
||||
@@ -68,20 +68,30 @@ assign(ReactDOMTextComponent.prototype, {
|
||||
* @return {string} Markup for this text node.
|
||||
* @internal
|
||||
*/
|
||||
mountComponent: function(rootID, transaction, context) {
|
||||
mountComponent: function(
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
) {
|
||||
if (__DEV__) {
|
||||
if (context[validateDOMNesting.ancestorInfoContextKey]) {
|
||||
validateDOMNesting(
|
||||
'span',
|
||||
null,
|
||||
context[validateDOMNesting.ancestorInfoContextKey]
|
||||
);
|
||||
var parentInfo;
|
||||
if (nativeParent != null) {
|
||||
parentInfo = nativeParent._ancestorInfo;
|
||||
} else if (nativeContainerInfo != null) {
|
||||
parentInfo = nativeContainerInfo._ancestorInfo;
|
||||
}
|
||||
if (parentInfo) {
|
||||
// parentInfo should always be present except for the top-level
|
||||
// component when server rendering
|
||||
validateDOMNesting(this._tag, this, parentInfo);
|
||||
}
|
||||
}
|
||||
|
||||
this._rootNodeID = rootID;
|
||||
if (transaction.useCreateElement) {
|
||||
var ownerDocument = context[ReactMount.ownerDocumentContextKey];
|
||||
var ownerDocument = nativeContainerInfo._ownerDocument;
|
||||
var el = ownerDocument.createElement('span');
|
||||
this._nativeNode = el;
|
||||
DOMPropertyOperations.setAttributeForID(el, rootID);
|
||||
|
||||
@@ -11,40 +11,25 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
var instantiateReactComponent = require('instantiateReactComponent');
|
||||
|
||||
describe('Danger', function() {
|
||||
|
||||
describe('dangerouslyRenderMarkup', function() {
|
||||
var Danger;
|
||||
var transaction;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
Danger = require('Danger');
|
||||
|
||||
var ReactReconcileTransaction = require('ReactReconcileTransaction');
|
||||
transaction = new ReactReconcileTransaction(/* forceHTML */ true);
|
||||
});
|
||||
|
||||
it('should render markup', function() {
|
||||
var markup = instantiateReactComponent(
|
||||
<div />
|
||||
).mountComponent('.rX', transaction, {});
|
||||
var markup = '<div data-reactid=".rX"></div>';
|
||||
var output = Danger.dangerouslyRenderMarkup([markup])[0];
|
||||
|
||||
expect(output.nodeName).toBe('DIV');
|
||||
});
|
||||
|
||||
it('should render markup with props', function() {
|
||||
var markup = instantiateReactComponent(
|
||||
<div className="foo" />
|
||||
).mountComponent(
|
||||
'.rX',
|
||||
transaction,
|
||||
{}
|
||||
);
|
||||
var markup = '<div class="foo" data-reactid=".rX"></div>';
|
||||
var output = Danger.dangerouslyRenderMarkup([markup])[0];
|
||||
|
||||
expect(output.nodeName).toBe('DIV');
|
||||
@@ -52,9 +37,7 @@ describe('Danger', function() {
|
||||
});
|
||||
|
||||
it('should render wrapped markup', function() {
|
||||
var markup = instantiateReactComponent(
|
||||
<th />
|
||||
).mountComponent('.rX', transaction, {});
|
||||
var markup = '<th data-reactid=".rX"></th>';
|
||||
var output = Danger.dangerouslyRenderMarkup([markup])[0];
|
||||
|
||||
expect(output.nodeName).toBe('TH');
|
||||
|
||||
@@ -96,6 +96,8 @@ var ReactCompositeComponentMixin = {
|
||||
this._currentElement = element;
|
||||
this._rootNodeID = null;
|
||||
this._instance = null;
|
||||
this._nativeParent = null;
|
||||
this._nativeContainerInfo = null;
|
||||
|
||||
// See ReactUpdateQueue
|
||||
this._pendingElement = null;
|
||||
@@ -122,10 +124,18 @@ var ReactCompositeComponentMixin = {
|
||||
* @final
|
||||
* @internal
|
||||
*/
|
||||
mountComponent: function(rootID, transaction, context) {
|
||||
mountComponent: function(
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
) {
|
||||
this._context = context;
|
||||
this._mountOrder = nextMountID++;
|
||||
this._rootNodeID = rootID;
|
||||
this._nativeParent = nativeParent;
|
||||
this._nativeContainerInfo = nativeContainerInfo;
|
||||
|
||||
var publicProps = this._processProps(this._currentElement.props);
|
||||
var publicContext = this._processContext(context);
|
||||
@@ -288,6 +298,8 @@ var ReactCompositeComponentMixin = {
|
||||
this._renderedComponent,
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
this._processChildContext(context)
|
||||
);
|
||||
if (inst.componentDidMount) {
|
||||
@@ -739,6 +751,8 @@ var ReactCompositeComponentMixin = {
|
||||
this._renderedComponent,
|
||||
this._rootNodeID,
|
||||
transaction,
|
||||
this._nativeParent,
|
||||
this._nativeContainerInfo,
|
||||
this._processChildContext(context)
|
||||
);
|
||||
this._replaceNodeWithMarkup(oldNativeNode, nextMarkup);
|
||||
|
||||
@@ -33,13 +33,21 @@ var ReactEmptyComponent = function(instantiate) {
|
||||
assign(ReactEmptyComponent.prototype, {
|
||||
construct: function(element) {
|
||||
},
|
||||
mountComponent: function(rootID, transaction, context) {
|
||||
mountComponent: function(
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
) {
|
||||
ReactEmptyComponentRegistry.registerNullComponentID(rootID);
|
||||
this._rootNodeID = rootID;
|
||||
return ReactReconciler.mountComponent(
|
||||
this._renderedComponent,
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
);
|
||||
},
|
||||
|
||||
@@ -255,6 +255,8 @@ var ReactMultiChild = {
|
||||
child,
|
||||
rootID,
|
||||
transaction,
|
||||
this,
|
||||
this._nativeContainerInfo,
|
||||
context
|
||||
);
|
||||
child._mountIndex = index++;
|
||||
@@ -503,6 +505,8 @@ var ReactMultiChild = {
|
||||
child,
|
||||
rootID,
|
||||
transaction,
|
||||
this,
|
||||
this._nativeContainerInfo,
|
||||
context
|
||||
);
|
||||
child._mountIndex = index;
|
||||
|
||||
@@ -29,12 +29,27 @@ var ReactReconciler = {
|
||||
* @param {ReactComponent} internalInstance
|
||||
* @param {string} rootID DOM ID of the root node.
|
||||
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
||||
* @param {?object} the containing native component instance
|
||||
* @param {?object} info about the native container
|
||||
* @return {?string} Rendered markup to be inserted into the DOM.
|
||||
* @final
|
||||
* @internal
|
||||
*/
|
||||
mountComponent: function(internalInstance, rootID, transaction, context) {
|
||||
var markup = internalInstance.mountComponent(rootID, transaction, context);
|
||||
mountComponent: function(
|
||||
internalInstance,
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
) {
|
||||
var markup = internalInstance.mountComponent(
|
||||
rootID,
|
||||
transaction,
|
||||
nativeParent,
|
||||
nativeContainerInfo,
|
||||
context
|
||||
);
|
||||
if (internalInstance._currentElement &&
|
||||
internalInstance._currentElement.ref != null) {
|
||||
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
|
||||
|
||||
@@ -446,7 +446,7 @@ ReactShallowRenderer.prototype._render = function(element, transaction, context)
|
||||
var instance = new ShallowComponentWrapper(element.type);
|
||||
instance.construct(element);
|
||||
|
||||
instance.mountComponent(rootID, transaction, context);
|
||||
instance.mountComponent(rootID, transaction, null, null, context);
|
||||
|
||||
this._instance = instance;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user