@samitouri / QOS-React-2 / commits / 49f174cdad

Server rendering: rendering of entire document using React.

Summary: Allows rendering of React into the "document" as opposed to into a particular node. To recap some basics: document: One level above the <html> tag - like the browser. document.documentElement: <body> To support full-page server side rendering, we need to be able to render *everything* including the HTML/BODY tags. This allows that.

Jordan Walke committed Aug 23, 2013 at 02:04 UTC 49f174cdad9db9d7b71b55e14b080e8508f629a8
4 files changed +23 -3
src/core/ReactComponentBrowserEnvironment.js
+7 -1
@@ -29,6 +29,9 @@ var getReactRootElementInContainer = require('getReactRootElementInContainer');
29 var invariant = require('invariant');
30
31
32 +var ELEMENT_NODE_TYPE = 1;
33 +var DOC_NODE_TYPE = 9;
34 +
35
36 /**
37 * Abstracts away all functionality of `ReactComponent` requires knowledge of
@@ -78,7 +81,10 @@ var ReactComponentBrowserEnvironment = {
81 */
82 mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
83 invariant(
81 - container && container.nodeType === 1,
84 + container && (
85 + container.nodeType === ELEMENT_NODE_TYPE ||
86 + container.nodeType === DOC_NODE_TYPE && ReactMount.allowFullPageRender
87 + ),
88 'mountComponentIntoNode(...): Target container is not a DOM element.'
89 );
90 if (shouldReuseMarkup) {
src/core/ReactMount.js
+4
@@ -197,6 +197,10 @@ function purgeID(id) {
197 * Inside of `container`, the first element rendered is the "reactRoot".
198 */
199 var ReactMount = {
200 + /**
201 + * Safety guard to prevent accidentally rendering over the entire HTML tree.
202 + */
203 + allowFullPageRender: false,
204
205 /** Time spent generating markup. */
206 totalInstantiationTime: 0,
src/vendor/core/createNodesFromMarkup.js
+5 -1
@@ -19,6 +19,8 @@
19
20 /*jslint evil: true, sub: true */
21
22 +var ExecutionEnvironment = require('ExecutionEnvironment');
23 +
24 var createArrayFrom = require('createArrayFrom');
25 var getMarkupWrap = require('getMarkupWrap');
26 var invariant = require('invariant');
@@ -26,7 +28,8 @@ var invariant = require('invariant');
28 /**
29 * Dummy container used to render all markup.
30 */
29 -var dummyNode = document.createElement('div');
31 +var dummyNode =
32 + ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
33
34 /**
35 * Pattern used by `getNodeName`.
@@ -56,6 +59,7 @@ function getNodeName(markup) {
59 */
60 function createNodesFromMarkup(markup, handleScript) {
61 var node = dummyNode;
62 + invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
63 var nodeName = getNodeName(markup);
64
65 var wrap = nodeName && getMarkupWrap(nodeName);
src/vendor/core/getMarkupWrap.js
+7 -1
@@ -16,10 +16,15 @@
16 * @providesModule getMarkupWrap
17 */
18
19 +var ExecutionEnvironment = require('ExecutionEnvironment');
20 +
21 +var invariant = require('invariant');
22 +
23 /**
24 * Dummy container used to detect which wraps are necessary.
25 */
22 -var dummyNode = document.createElement('div');
26 +var dummyNode =
27 + ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
28
29 /**
30 * Some browsers cannot use `innerHTML` to render certain elements standalone,
@@ -55,6 +60,7 @@ var markupWrap = {
60 * @return {?array} Markup wrap configuration, if applicable.
61 */
62 function getMarkupWrap(nodeName) {
63 + invariant(!!dummyNode, 'Markup wrapping node not initialized');
64 if (!markupWrap.hasOwnProperty(nodeName)) {
65 nodeName = '*';
66 }