Skip to content

Commit

Permalink
Merge pull request facebook#2509 from jsfb/use-parent-context
Browse files Browse the repository at this point in the history
Initial implementation of issue facebook#2112
  • Loading branch information
jimfb committed Nov 18, 2014
2 parents fba8be3 + 081feeb commit 89aaf73
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 93 deletions.
13 changes: 9 additions & 4 deletions src/browser/server/ReactServerRendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactServerRenderingTransaction =
require('ReactServerRenderingTransaction');

var emptyObject = require('emptyObject');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');

/**
* @param {ReactElement} element
* @param {?object} context
* @return {string} the HTML markup
*/
function renderToString(element) {
function renderToString(element, context) {
if(context === undefined) context = emptyObject;
invariant(
ReactElement.isValidElement(element),
'renderToString(): You must pass a valid ReactElement.'
Expand All @@ -37,7 +40,7 @@ function renderToString(element) {

return transaction.perform(function() {
var componentInstance = instantiateReactComponent(element, null);
var markup = componentInstance.mountComponent(id, transaction, 0);
var markup = componentInstance.mountComponent(id, transaction, 0, context);
return ReactMarkupChecksum.addChecksumToMarkup(markup);
}, null);
} finally {
Expand All @@ -47,10 +50,12 @@ function renderToString(element) {

/**
* @param {ReactElement} element
* @param {?object} context
* @return {string} the HTML markup, without the extra React ID and checksum
* (for generating static pages)
*/
function renderToStaticMarkup(element) {
function renderToStaticMarkup(element, context) {
if(context === undefined) context = emptyObject;
invariant(
ReactElement.isValidElement(element),
'renderToStaticMarkup(): You must pass a valid ReactElement.'
Expand All @@ -63,7 +68,7 @@ function renderToStaticMarkup(element) {

return transaction.perform(function() {
var componentInstance = instantiateReactComponent(element, null);
return componentInstance.mountComponent(id, transaction, 0);
return componentInstance.mountComponent(id, transaction, 0, context);
}, null);
} finally {
ReactServerRenderingTransaction.release(transaction);
Expand Down
35 changes: 22 additions & 13 deletions src/browser/ui/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,21 @@ ReactDOMComponent.Mixin = {
mountComponent: ReactPerf.measure(
'ReactDOMComponent',
'mountComponent',
function(rootID, transaction, mountDepth) {
function(rootID, transaction, mountDepth, context) {
invariant(context !== undefined, "Context is required parameter");
ReactComponent.Mixin.mountComponent.call(
this,
rootID,
transaction,
mountDepth
mountDepth,
context
);
this._previousStyleCopy = null;
assertValidProps(this._currentElement.props);
var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
return (
this._createOpenTagMarkupAndPutListeners(transaction) +
this._createContentMarkup(transaction) +
this._createContentMarkup(transaction, context) +
closeTag
);
}
Expand Down Expand Up @@ -242,9 +244,10 @@ ReactDOMComponent.Mixin = {
*
* @private
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {object} context
* @return {string} Content markup.
*/
_createContentMarkup: function(transaction) {
_createContentMarkup: function(transaction, context) {
var prefix = '';
if (this._tag === 'listing' ||
this._tag === 'pre' ||
Expand Down Expand Up @@ -272,15 +275,17 @@ ReactDOMComponent.Mixin = {
} else if (childrenToUse != null) {
var mountImages = this.mountChildren(
childrenToUse,
transaction
transaction,
context
);
return prefix + mountImages.join('');
}
}
return prefix;
},

receiveComponent: function(nextElement, transaction) {
receiveComponent: function(nextElement, transaction, context) {
invariant(context !== undefined, "Context is required parameter");
if (nextElement === this._currentElement &&
nextElement._owner != null) {
// Since elements are immutable after the owner is rendered,
Expand All @@ -295,7 +300,7 @@ ReactDOMComponent.Mixin = {

var prevElement = this._currentElement;
this._currentElement = nextElement;
this.updateComponent(transaction, prevElement, nextElement);
this.updateComponent(transaction, prevElement, nextElement, context);
},

/**
Expand All @@ -311,16 +316,19 @@ ReactDOMComponent.Mixin = {
updateComponent: ReactPerf.measure(
'ReactDOMComponent',
'updateComponent',
function(transaction, prevElement, nextElement) {
function(transaction, prevElement, nextElement, context) {
if(context === undefined) throw new Error("Context required for mounting");
if(context === null) throw new Error("Assert: context is not null");
assertValidProps(this._currentElement.props);
ReactComponent.Mixin.updateComponent.call(
this,
transaction,
prevElement,
nextElement
nextElement,
context
);
this._updateDOMProperties(prevElement.props, transaction);
this._updateDOMChildren(prevElement.props, transaction);
this._updateDOMChildren(prevElement.props, transaction, context);
}
),

Expand Down Expand Up @@ -428,7 +436,8 @@ ReactDOMComponent.Mixin = {
* @param {object} lastProps
* @param {ReactReconcileTransaction} transaction
*/
_updateDOMChildren: function(lastProps, transaction) {
_updateDOMChildren: function(lastProps, transaction, context) {
invariant(context !== undefined, "Context is required parameter");
var nextProps = this._currentElement.props;

var lastContent =
Expand All @@ -452,7 +461,7 @@ ReactDOMComponent.Mixin = {
var lastHasContentOrHtml = lastContent != null || lastHtml != null;
var nextHasContentOrHtml = nextContent != null || nextHtml != null;
if (lastChildren != null && nextChildren == null) {
this.updateChildren(null, transaction);
this.updateChildren(null, transaction, context);
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
this.updateTextContent('');
}
Expand All @@ -469,7 +478,7 @@ ReactDOMComponent.Mixin = {
);
}
} else if (nextChildren != null) {
this.updateChildren(nextChildren, transaction);
this.updateChildren(nextChildren, transaction, context);
}
},

Expand Down
2 changes: 1 addition & 1 deletion src/browser/ui/ReactDOMTextComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ assign(ReactDOMTextComponent.prototype, {
* @return {string} Markup for this text node.
* @internal
*/
mountComponent: function(rootID, transaction, mountDepth) {
mountComponent: function(rootID, transaction, mountDepth, context) {
this._rootNodeID = rootID;
var escapedText = escapeTextForBrowser(this._stringText);

Expand Down
3 changes: 2 additions & 1 deletion src/browser/ui/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactPerf = require('ReactPerf');
var ReactUpdates = require('ReactUpdates');

var emptyObject = require('emptyObject');
var containsNode = require('containsNode');
var deprecated = require('deprecated');
var getReactRootElementInContainer = require('getReactRootElementInContainer');
Expand Down Expand Up @@ -224,7 +225,7 @@ function mountComponentIntoNode(
container,
transaction,
shouldReuseMarkup) {
var markup = this.mountComponent(rootID, transaction, 0);
var markup = this.mountComponent(rootID, transaction, 0, emptyObject);
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
}

Expand Down
4 changes: 2 additions & 2 deletions src/browser/ui/__tests__/ReactDOMComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ describe('ReactDOMComponent', function() {

genMarkup = function(props) {
var transaction = new ReactReconcileTransaction();
return (new NodeStub(props))._createContentMarkup(transaction);
return (new NodeStub(props))._createContentMarkup(transaction, {});
};

this.addMatchers({
Expand Down Expand Up @@ -328,7 +328,7 @@ describe('ReactDOMComponent', function() {
_owner: null,
_context: null
});
return stubComponent.mountComponent('test', transaction, 0);
return stubComponent.mountComponent('test', transaction, 0, {});
};
});

Expand Down
6 changes: 3 additions & 3 deletions src/browser/ui/dom/__tests__/Danger-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('Danger', function() {
it('should render markup', function() {
var markup = instantiateReactComponent(
<div />
).mountComponent('.rX', transaction, 0);
).mountComponent('.rX', transaction, 0, {});
var output = Danger.dangerouslyRenderMarkup([markup])[0];

expect(output.nodeName).toBe('DIV');
Expand All @@ -44,7 +44,7 @@ describe('Danger', function() {
).mountComponent(
'.rX',
transaction,
0
0, {}
);
var output = Danger.dangerouslyRenderMarkup([markup])[0];

Expand All @@ -55,7 +55,7 @@ describe('Danger', function() {
it('should render wrapped markup', function() {
var markup = instantiateReactComponent(
<th />
).mountComponent('.rX', transaction, 0);
).mountComponent('.rX', transaction, 0, {});
var output = Danger.dangerouslyRenderMarkup([markup])[0];

expect(output.nodeName).toBe('TH');
Expand Down
7 changes: 4 additions & 3 deletions src/core/ReactComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ var ReactComponent = {
// We keep the old element and a reference to the pending element
// to track updates.
this._currentElement = element;

this._rootNodeID = null;
this._mountIndex = 0;
this._mountDepth = 0;
Expand All @@ -134,7 +133,8 @@ var ReactComponent = {
* @return {?string} Rendered markup to be inserted into the DOM.
* @internal
*/
mountComponent: function(rootID, transaction, mountDepth) {
mountComponent: function(rootID, transaction, mountDepth, context) {
invariant(context !== undefined, "Context is required parameter");
var ref = this._currentElement.ref;
if (ref != null) {
var owner = this._currentElement._owner;
Expand Down Expand Up @@ -173,7 +173,8 @@ var ReactComponent = {
* @param {object} nextElement
* @internal
*/
updateComponent: function(transaction, prevElement, nextElement) {
updateComponent: function(transaction, prevElement, nextElement, context) {
invariant(context !== undefined, "Context is required parameter");
// If either the owner or a `ref` has changed, make sure the newest owner
// has stored a reference to `this`, and the previous owner (if different)
// has forgotten the reference to `this`. We use the element instead
Expand Down
Loading

0 comments on commit 89aaf73

Please sign in to comment.