UNPKG

motion

Version:

motion - moving development forward

147 lines (129 loc) 4.85 kB
/** * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule ReactDOMTextComponent */ 'use strict'; var DOMChildrenOperations = require('./DOMChildrenOperations'); var DOMLazyTree = require('./DOMLazyTree'); var DOMPropertyOperations = require('./DOMPropertyOperations'); var ReactDOMComponentTree = require('./ReactDOMComponentTree'); var ReactPerf = require('./ReactPerf'); var assign = require('./Object.assign'); var escapeTextContentForBrowser = require('./escapeTextContentForBrowser'); var validateDOMNesting = require('./validateDOMNesting'); var getNode = ReactDOMComponentTree.getNodeFromInstance; /** * Text nodes violate a couple assumptions that React makes about components: * * - When mounting text into the DOM, adjacent text nodes are merged. * - Text nodes cannot be assigned a React root ID. * * This component is used to wrap strings in elements so that they can undergo * the same reconciliation that is applied to elements. * * TODO: Investigate representing React components in the DOM with text nodes. * * @class ReactDOMTextComponent * @extends ReactComponent * @internal */ var ReactDOMTextComponent = function (props) { // This constructor and its argument is currently used by mocks. }; assign(ReactDOMTextComponent.prototype, { /** * @param {ReactText} text * @internal */ construct: function (text) { // TODO: This is really a ReactText (ReactNode), not a ReactElement this._currentElement = text; this._stringText = '' + text; // ReactDOMComponentTree uses these: this._nativeNode = null; this._nativeParent = null; // Properties this._domID = null; this._mountIndex = 0; }, /** * Creates the markup for this text node. This node is not intended to have * any features besides containing text content. * * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @return {string} Markup for this text node. * @internal */ mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) { if (process.env.NODE_ENV !== 'production') { var parentInfo; if (nativeParent != null) { parentInfo = nativeParent._ancestorInfo; } else if (nativeContainerInfo != null) { parentInfo = nativeContainerInfo._ancestorInfo; } if (parentInfo) { // parentInfo should always be present except for the top-level // component when server rendering validateDOMNesting('span', this, parentInfo); } } var domID = nativeContainerInfo._idCounter++; this._domID = domID; this._nativeParent = nativeParent; if (transaction.useCreateElement) { var ownerDocument = nativeContainerInfo._ownerDocument; var el = ownerDocument.createElement('span'); ReactDOMComponentTree.precacheNode(this, el); var lazyTree = DOMLazyTree(el); DOMLazyTree.queueText(lazyTree, this._stringText); return lazyTree; } else { var escapedText = escapeTextContentForBrowser(this._stringText); if (transaction.renderToStaticMarkup) { // Normally we'd wrap this in a `span` for the reasons stated above, but // since this is a situation where React won't take over (static pages), // we can simply return the text as it is. return escapedText; } return '<span ' + DOMPropertyOperations.createMarkupForID(domID) + '>' + escapedText + '</span>'; } }, /** * Updates this component by updating the text content. * * @param {ReactText} nextText The next text content * @param {ReactReconcileTransaction} transaction * @internal */ receiveComponent: function (nextText, transaction) { if (nextText !== this._currentElement) { this._currentElement = nextText; var nextStringText = '' + nextText; if (nextStringText !== this._stringText) { // TODO: Save this as pending props and use performUpdateIfNecessary // and/or updateComponent to do the actual update for consistency with // other component types? this._stringText = nextStringText; DOMChildrenOperations.updateTextContent(getNode(this), nextStringText); } } }, getNativeNode: function () { return getNode(this); }, unmountComponent: function () { ReactDOMComponentTree.uncacheNode(this); } }); ReactPerf.measureMethods(ReactDOMTextComponent.prototype, 'ReactDOMTextComponent', { mountComponent: 'mountComponent', receiveComponent: 'receiveComponent' }); module.exports = ReactDOMTextComponent;