@samitouri / QOS-React-2 / commits / a160f3ecfa

Fixes #9667: Updated createTextInstance to create the text node on correct document (#10723)

Kenneth Chau committed Sep 22, 2017 at 16:08 UTC a160f3ecfa2fff67d8dec9c22a63300b78d3ad0c
3 files changed +49 -5
src/renderers/dom/fiber/ReactDOMFiberComponent.js
+17 -4
@@ -157,6 +157,14 @@ function ensureListeningTo(rootContainerElement, registrationName) {
157 listenTo(registrationName, doc);
158 }
159
160 +function getOwnerDocumentFromRootContainer(
161 + rootContainerElement: Element | Document,
162 +): Document {
163 + return rootContainerElement.nodeType === DOCUMENT_NODE
164 + ? (rootContainerElement: any)
165 + : rootContainerElement.ownerDocument;
166 +}
167 +
168 // There are so many media events, it makes sense to just
169 // maintain a list rather than create a `trapBubbledEvent` for each
170 var mediaEvents = {
@@ -296,10 +304,9 @@ var ReactDOMFiberComponent = {
304 ): Element {
305 // We create tags in the namespace of their parent container, except HTML
306 // tags get no namespace.
299 - var ownerDocument: Document = rootContainerElement.nodeType ===
300 - DOCUMENT_NODE
301 - ? (rootContainerElement: any)
302 - : rootContainerElement.ownerDocument;
307 + var ownerDocument: Document = getOwnerDocumentFromRootContainer(
308 + rootContainerElement,
309 + );
310 var domElement: Element;
311 var namespaceURI = parentNamespace;
312 if (namespaceURI === HTML_NAMESPACE) {
@@ -362,6 +369,12 @@ var ReactDOMFiberComponent = {
369 return domElement;
370 },
371
372 + createTextNode(text: string, rootContainerElement: Element | Document): Text {
373 + return getOwnerDocumentFromRootContainer(
374 + rootContainerElement,
375 + ).createTextNode(text);
376 + },
377 +
378 setInitialProperties(
379 domElement: Element,
380 tag: string,
src/renderers/dom/fiber/ReactDOMFiberEntry.js
+2 -1
@@ -46,6 +46,7 @@ var invariant = require('fbjs/lib/invariant');
46 var {getChildNamespace} = DOMNamespaces;
47 var {
48 createElement,
49 + createTextNode,
50 setInitialProperties,
51 diffProperties,
52 updateProperties,
@@ -368,7 +369,7 @@ var DOMRenderer = ReactFiberReconciler({
369 const hostContextDev = ((hostContext: any): HostContextDev);
370 validateDOMNesting(null, text, null, hostContextDev.ancestorInfo);
371 }
371 - var textNode: TextInstance = document.createTextNode(text);
372 + var textNode: TextInstance = createTextNode(text, rootContainerInstance);
373 precacheFiberNode(internalInstanceHandle, textNode);
374 return textNode;
375 },
src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
+30
@@ -1117,5 +1117,35 @@ describe('ReactDOMFiber', () => {
1117 'to empty a container.',
1118 );
1119 });
1120 +
1121 + it('should render a text component with a text DOM node on the same document as the container', () => {
1122 + // 1. Create a new document through the use of iframe
1123 + // 2. Set up the spy to make asserts when a text component
1124 + // is rendered inside the iframe container
1125 + var textContent = 'Hello world';
1126 + var iframe = document.createElement('iframe');
1127 + document.body.appendChild(iframe);
1128 + var iframeDocument = iframe.contentDocument;
1129 + iframeDocument.write(
1130 + '<!DOCTYPE html><html><head></head><body><div></div></body></html>',
1131 + );
1132 + iframeDocument.close();
1133 + var iframeContainer = iframeDocument.body.firstChild;
1134 +
1135 + var actualDocument;
1136 + var textNode;
1137 +
1138 + spyOn(iframeContainer, 'appendChild').and.callFake(node => {
1139 + actualDocument = node.ownerDocument;
1140 + textNode = node;
1141 + });
1142 +
1143 + ReactDOM.render(textContent, iframeContainer);
1144 +
1145 + expect(textNode.textContent).toBe(textContent);
1146 + expect(actualDocument).not.toBe(document);
1147 + expect(actualDocument).toBe(iframeDocument);
1148 + expect(iframeContainer.appendChild).toHaveBeenCalledTimes(1);
1149 + });
1150 }
1151 });