From ac9dd922726b5e886cada4788cf43906f18aedf5 Mon Sep 17 00:00:00 2001
From: Andrey Popp <8mayday@gmail.com>
Date: Tue, 15 Oct 2013 03:21:29 +0400
Subject: [PATCH] Fix unmounting components mounted into doc element
If we are to unmount a component mounted into a document element we should
unmount it from document.documentElement and not from document.firstChild which
is a doctype element in this specific case.
---
src/core/ReactMount.js | 6 ++
.../__tests__/ReactRenderDocument-test.js | 60 +++++++++++++++++++
src/core/getReactRootElementInContainer.js | 15 ++++-
3 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/src/core/ReactMount.js b/src/core/ReactMount.js
index 217411e41b4de..29d8b626a94c8 100644
--- a/src/core/ReactMount.js
+++ b/src/core/ReactMount.js
@@ -430,6 +430,10 @@ var ReactMount = {
unmountComponentFromNode: function(instance, container) {
instance.unmountComponent();
+ if (container.nodeType === DOC_NODE_TYPE) {
+ container = container.documentElement;
+ }
+
// http://jsperf.com/emptying-a-node
while (container.lastChild) {
container.removeChild(container.lastChild);
@@ -592,6 +596,8 @@ var ReactMount = {
ATTR_NAME: ATTR_NAME,
+ getReactRootID: getReactRootID,
+
getID: getID,
setID: setID,
diff --git a/src/core/__tests__/ReactRenderDocument-test.js b/src/core/__tests__/ReactRenderDocument-test.js
index eec3b516da749..dd5250811ca0c 100644
--- a/src/core/__tests__/ReactRenderDocument-test.js
+++ b/src/core/__tests__/ReactRenderDocument-test.js
@@ -39,6 +39,66 @@ describe('rendering React components at document', function() {
testDocument = getTestDocument();
});
+ it('should be able to get root component id for document node', function() {
+ if (!testDocument) {
+ // These tests are not applicable in jst, since jsdom is buggy.
+ return;
+ }
+
+ var Root = React.createClass({
+ render: function() {
+ return (
+
+
+ Hello World
+
+
+ Hello world
+
+
+ );
+ }
+ });
+
+ ReactMount.allowFullPageRender = true;
+ var component = React.renderComponent(, testDocument);
+ expect(testDocument.body.innerHTML).toBe(' Hello world ');
+
+ var componentID = ReactMount.getReactRootID(testDocument);
+ expect(componentID).toBe(component._rootNodeID);
+ });
+
+ it('should be able to unmount component from document node', function() {
+ if (!testDocument) {
+ // These tests are not applicable in jst, since jsdom is buggy.
+ return;
+ }
+
+ var Root = React.createClass({
+ render: function() {
+ return (
+
+
+ Hello World
+
+
+ Hello world
+
+
+ );
+ }
+ });
+
+ ReactMount.allowFullPageRender = true;
+ React.renderComponent(, testDocument);
+ expect(testDocument.body.innerHTML).toBe(' Hello world ');
+
+ var unmounted = React.unmountComponentAtNode(testDocument);
+ expect(unmounted).toBe(true);
+ expect(testDocument.documentElement).not.toBe(null);
+ expect(testDocument.documentElement.innerHTML).toBe('');
+ });
+
it('should be able to switch root constructors via state', function() {
if (!testDocument) {
// These tests are not applicable in jst, since jsdom is buggy.
diff --git a/src/core/getReactRootElementInContainer.js b/src/core/getReactRootElementInContainer.js
index ac306a585028b..f90f5178982f1 100644
--- a/src/core/getReactRootElementInContainer.js
+++ b/src/core/getReactRootElementInContainer.js
@@ -18,12 +18,23 @@
"use strict";
+var DOC_NODE_TYPE = 9;
+
/**
- * @param {DOMElement} container DOM element that may contain a React component
+ * @param {DOMElement|DOMDocument} container DOM element that may contain
+ * a React component
* @return {?*} DOM element that may have the reactRoot ID, or null.
*/
function getReactRootElementInContainer(container) {
- return container && container.firstChild;
+ if (!container) {
+ return null;
+ }
+
+ if (container.nodeType === DOC_NODE_TYPE) {
+ return container.documentElement;
+ } else {
+ return container.firstChild;
+ }
}
module.exports = getReactRootElementInContainer;