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

This commit is contained in:
Kenneth Chau
2017-09-22 16:08:19 -07:00
committed by Sophie Alpert
parent cdfbe6bb04
commit a160f3ecfa
3 changed files with 49 additions and 5 deletions

View File

@@ -157,6 +157,14 @@ function ensureListeningTo(rootContainerElement, registrationName) {
listenTo(registrationName, doc);
}
function getOwnerDocumentFromRootContainer(
rootContainerElement: Element | Document,
): Document {
return rootContainerElement.nodeType === DOCUMENT_NODE
? (rootContainerElement: any)
: rootContainerElement.ownerDocument;
}
// There are so many media events, it makes sense to just
// maintain a list rather than create a `trapBubbledEvent` for each
var mediaEvents = {
@@ -296,10 +304,9 @@ var ReactDOMFiberComponent = {
): Element {
// We create tags in the namespace of their parent container, except HTML
// tags get no namespace.
var ownerDocument: Document = rootContainerElement.nodeType ===
DOCUMENT_NODE
? (rootContainerElement: any)
: rootContainerElement.ownerDocument;
var ownerDocument: Document = getOwnerDocumentFromRootContainer(
rootContainerElement,
);
var domElement: Element;
var namespaceURI = parentNamespace;
if (namespaceURI === HTML_NAMESPACE) {
@@ -362,6 +369,12 @@ var ReactDOMFiberComponent = {
return domElement;
},
createTextNode(text: string, rootContainerElement: Element | Document): Text {
return getOwnerDocumentFromRootContainer(
rootContainerElement,
).createTextNode(text);
},
setInitialProperties(
domElement: Element,
tag: string,

View File

@@ -46,6 +46,7 @@ var invariant = require('fbjs/lib/invariant');
var {getChildNamespace} = DOMNamespaces;
var {
createElement,
createTextNode,
setInitialProperties,
diffProperties,
updateProperties,
@@ -368,7 +369,7 @@ var DOMRenderer = ReactFiberReconciler({
const hostContextDev = ((hostContext: any): HostContextDev);
validateDOMNesting(null, text, null, hostContextDev.ancestorInfo);
}
var textNode: TextInstance = document.createTextNode(text);
var textNode: TextInstance = createTextNode(text, rootContainerInstance);
precacheFiberNode(internalInstanceHandle, textNode);
return textNode;
},

View File

@@ -1117,5 +1117,35 @@ describe('ReactDOMFiber', () => {
'to empty a container.',
);
});
it('should render a text component with a text DOM node on the same document as the container', () => {
// 1. Create a new document through the use of iframe
// 2. Set up the spy to make asserts when a text component
// is rendered inside the iframe container
var textContent = 'Hello world';
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var iframeDocument = iframe.contentDocument;
iframeDocument.write(
'<!DOCTYPE html><html><head></head><body><div></div></body></html>',
);
iframeDocument.close();
var iframeContainer = iframeDocument.body.firstChild;
var actualDocument;
var textNode;
spyOn(iframeContainer, 'appendChild').and.callFake(node => {
actualDocument = node.ownerDocument;
textNode = node;
});
ReactDOM.render(textContent, iframeContainer);
expect(textNode.textContent).toBe(textContent);
expect(actualDocument).not.toBe(document);
expect(actualDocument).toBe(iframeDocument);
expect(iframeContainer.appendChild).toHaveBeenCalledTimes(1);
});
}
});