Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of issue #2112 #2509

Merged
merged 1 commit into from
Nov 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:( @sebmarkbage I'm going to work on the style automation & linting as much as possible, but let's try to catch things like this (space before open paren, newlines with braces for ifs). Especially important for new contributors.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zpao No time. We needed to avoid another merge-hell.

However, I missed that renderToString still accepts a context. It shouldn't.

function renderToString(element, context) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renderToString fixed in #2565

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