From f49620053f19861b27366be3af47349a23b656cb Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 30 Mar 2018 12:57:27 -0400 Subject: [PATCH] Element: Render RawHTML dangerously from serializer --- element/index.js | 9 +-------- element/serialize.js | 36 +++++++++++++++++++++--------------- element/test/serialize.js | 10 ++++++++-- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/element/index.js b/element/index.js index 297bbcb6c6c18a..5f296bac93a6c6 100644 --- a/element/index.js +++ b/element/index.js @@ -101,14 +101,7 @@ export { createPortal }; * * @return {string} HTML. */ -export function renderToString( element ) { - let rendered = serialize( element ); - - // Drop raw HTML wrappers (support dangerous inner HTML without wrapper) - rendered = rendered.replace( /<\/?wp-raw-html>/g, '' ); - - return rendered; -} +export { serialize as renderToString }; /** * Concatenate two or more React children objects. diff --git a/element/serialize.js b/element/serialize.js index 9b9c67552ffa81..b8d0f3d0604aaa 100644 --- a/element/serialize.js +++ b/element/serialize.js @@ -33,7 +33,7 @@ import { castArray, omit, kebabCase } from 'lodash'; /** * Internal dependencies */ -import { Fragment } from './'; +import { Fragment, RawHTML } from './'; /** * Valid attribute types. @@ -348,28 +348,34 @@ export function renderElement( element, context = {} ) { return renderChildren( element, context ); } - if ( typeof element === 'string' ) { - return escapeHTML( element ); - } + switch ( typeof element ) { + case 'string': + return escapeHTML( element ); - if ( typeof element === 'number' ) { - return element.toString(); + case 'number': + return element.toString(); } const { type: tagName, props } = element; - if ( tagName === Fragment ) { - return renderChildren( props.children, context ); + switch ( tagName ) { + case Fragment: + return renderChildren( props.children, context ); + + case RawHTML: + return props.children; } - if ( typeof tagName === 'string' ) { - return renderNativeComponent( tagName, props, context ); - } else if ( typeof tagName === 'function' ) { - if ( tagName.prototype && typeof tagName.prototype.render === 'function' ) { - return renderComponent( tagName, props, context ); - } + switch ( typeof tagName ) { + case 'string': + return renderNativeComponent( tagName, props, context ); + + case 'function': + if ( tagName.prototype && typeof tagName.prototype.render === 'function' ) { + return renderComponent( tagName, props, context ); + } - return renderElement( tagName( props, context ), context ); + return renderElement( tagName( props, context ), context ); } return ''; diff --git a/element/test/serialize.js b/element/test/serialize.js index d95b38692309d3..73c50056c601c5 100644 --- a/element/test/serialize.js +++ b/element/test/serialize.js @@ -6,7 +6,7 @@ import { noop } from 'lodash'; /** * Internal dependencies */ -import { Component, Fragment } from '../'; +import { Component, Fragment, RawHTML } from '../'; import serialize, { hasPrefix, renderElement, @@ -193,11 +193,17 @@ describe( 'renderElement()', () => { expect( result ).toBe( '' ); } ); - it( 'renders fragment as its inner children', () => { + it( 'renders Fragment as its inner children', () => { const result = renderElement( Hello ); expect( result ).toBe( 'Hello' ); } ); + + it( 'renders RawHTML as its unescaped children', () => { + const result = renderElement( { '' } ); + + expect( result ).toBe( '' ); + } ); } ); describe( 'renderNativeComponent()', () => {