diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index cf93f29b86d..b52fd5dcfdb 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -144,6 +144,12 @@ var omittedCloseTags = { // NOTE: menuitem's close tag should be omitted, but that causes problems. }; +var newlineEatingTags = { + 'listing': true, + 'pre': true, + 'textarea': true +}; + // For HTML, certain tags cannot have children. This has the same purpose as // `omittedCloseTags` except that `menuitem` should still have its closing tag. @@ -208,12 +214,12 @@ ReactDOMComponent.Mixin = { mountComponent: function(rootID, transaction, context) { this._rootNodeID = rootID; assertValidProps(this, this._currentElement.props); - var closeTag = omittedCloseTags[this._tag] ? '' : ''; - return ( - this._createOpenTagMarkupAndPutListeners(transaction) + - this._createContentMarkup(transaction, context) + - closeTag - ); + var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction); + var tagContent = this._createContentMarkup(transaction, context); + if (!tagContent && omittedCloseTags[this._tag]) { + return tagOpen + '/>'; + } + return tagOpen + '>' + tagContent + ''; }, /** @@ -260,11 +266,11 @@ ReactDOMComponent.Mixin = { // For static pages, no need to put React ID and checksum. Saves lots of // bytes. if (transaction.renderToStaticMarkup) { - return ret + '>'; + return ret; } var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); - return ret + ' ' + markupForID + '>'; + return ret + ' ' + markupForID; }, /** @@ -276,40 +282,45 @@ ReactDOMComponent.Mixin = { * @return {string} Content markup. */ _createContentMarkup: function(transaction, context) { - var prefix = ''; - if (this._tag === 'listing' || - this._tag === 'pre' || - this._tag === 'textarea') { - // Add an initial newline because browsers ignore the first newline in - // a ,
, or