Skip to content

Commit

Permalink
Merge pull request facebook#289 from jordwalke/ServerRenderingFixes3
Browse files Browse the repository at this point in the history
Server rendering: rendering of entire document using React.
  • Loading branch information
zpao committed Aug 23, 2013
2 parents 6ca8d31 + 748ed6c commit 946e9b0
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 6 deletions.
10 changes: 8 additions & 2 deletions src/core/ReactComponentBrowserEnvironment.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ var getReactRootElementInContainer = require('getReactRootElementInContainer');
var invariant = require('invariant');


var ELEMENT_NODE_TYPE = 1;
var DOC_NODE_TYPE = 9;


/**
* Abstracts away all functionality of `ReactComponent` requires knowledge of
Expand Down Expand Up @@ -78,8 +81,11 @@ var ReactComponentBrowserEnvironment = {
*/
mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
invariant(
container && container.nodeType === 1,
'mountComponentIntoNode(...): Target container is not a DOM element.'
container && (
container.nodeType === ELEMENT_NODE_TYPE ||
container.nodeType === DOC_NODE_TYPE && ReactMount.allowFullPageRender
),
'mountComponentIntoNode(...): Target container is not valid.'
);
if (shouldReuseMarkup) {
if (ReactMarkupChecksum.canReuseMarkup(
Expand Down
4 changes: 4 additions & 0 deletions src/core/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ function purgeID(id) {
* Inside of `container`, the first element rendered is the "reactRoot".
*/
var ReactMount = {
/**
* Safety guard to prevent accidentally rendering over the entire HTML tree.
*/
allowFullPageRender: false,

/** Time spent generating markup. */
totalInstantiationTime: 0,
Expand Down
20 changes: 18 additions & 2 deletions src/core/__tests__/ReactComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,48 @@
"use strict";

var React;
var ReactMount;
var ReactTestUtils;

var reactComponentExpect;

describe('ReactComponent', function() {
beforeEach(function() {
React = require('React');
ReactMount = require('ReactMount');
ReactTestUtils = require('ReactTestUtils');
reactComponentExpect = require('reactComponentExpect');
});

it('should not throw on full document rendering', function() {
var container = {nodeType: 9};
expect(function() {
React.renderComponent(<div></div>, container);
}).toThrow(
'Invariant Violation: mountComponentIntoNode(...): Target container is ' +
'not valid.'
);
ReactMount.allowFullPageRender = true;
expect(function() {
React.renderComponent(<div></div>, container);
}).not.toThrow();
});

it('should throw on invalid render targets', function() {
var container = document.createElement('div');
// jQuery objects are basically arrays; people often pass them in by mistake
expect(function() {
React.renderComponent(<div></div>, [container]);
}).toThrow(
'Invariant Violation: mountComponentIntoNode(...): Target container is ' +
'not a DOM element.'
'not valid.'
);

expect(function() {
React.renderComponent(<div></div>, null);
}).toThrow(
'Invariant Violation: mountComponentIntoNode(...): Target container is ' +
'not a DOM element.'
'not valid.'
);
});

Expand Down
File renamed without changes.
6 changes: 5 additions & 1 deletion src/vendor/core/createNodesFromMarkup.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@

/*jslint evil: true, sub: true */

var ExecutionEnvironment = require('ExecutionEnvironment');

var createArrayFrom = require('createArrayFrom');
var getMarkupWrap = require('getMarkupWrap');
var invariant = require('invariant');

/**
* Dummy container used to render all markup.
*/
var dummyNode = document.createElement('div');
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;

/**
* Pattern used by `getNodeName`.
Expand Down Expand Up @@ -56,6 +59,7 @@ function getNodeName(markup) {
*/
function createNodesFromMarkup(markup, handleScript) {
var node = dummyNode;
invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
var nodeName = getNodeName(markup);

var wrap = nodeName && getMarkupWrap(nodeName);
Expand Down
8 changes: 7 additions & 1 deletion src/vendor/core/getMarkupWrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@
* @providesModule getMarkupWrap
*/

var ExecutionEnvironment = require('ExecutionEnvironment');

var invariant = require('invariant');

/**
* Dummy container used to detect which wraps are necessary.
*/
var dummyNode = document.createElement('div');
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;

/**
* Some browsers cannot use `innerHTML` to render certain elements standalone,
Expand Down Expand Up @@ -55,6 +60,7 @@ var markupWrap = {
* @return {?array} Markup wrap configuration, if applicable.
*/
function getMarkupWrap(nodeName) {
invariant(!!dummyNode, 'Markup wrapping node not initialized');
if (!markupWrap.hasOwnProperty(nodeName)) {
nodeName = '*';
}
Expand Down

0 comments on commit 946e9b0

Please sign in to comment.