/** * Copyright 2013-2015, 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 * @typechecks static-only */ 'use strict'; var DOMPropertyOperations = require("./DOMPropertyOperations"); var ReactComponentBrowserEnvironment = require("./ReactComponentBrowserEnvironment"); var ReactDOMComponent = require("./ReactDOMComponent"); var assign = require("./Object.assign"); var escapeTextContentForBrowser = require("./escapeTextContentForBrowser"); /** * 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; // Properties this._rootNodeID = 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 {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @return {string} Markup for this text node. * @internal */ mountComponent: function(rootID, transaction, context) { this._rootNodeID = rootID; 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 ( '' + escapedText + '' ); }, /** * 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; ReactDOMComponent.BackendIDOperations.updateTextContentByID( this._rootNodeID, nextStringText ); } } }, unmountComponent: function() { ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); } }); module.exports = ReactDOMTextComponent;