From e9b711128b07daaca4698a1f85239053166d09f4 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 3 Nov 2017 13:45:07 +0100 Subject: [PATCH] Editable: Use valueToElement to render stored tree representation --- blocks/api/simple-dom.js | 8 ------- blocks/api/test/matchers.js | 32 +++++++++------------------- blocks/editable/index.js | 27 +++++++++++++---------- blocks/editable/test/index.js | 12 +++++------ blocks/editable/tinymce.js | 13 ++++++----- blocks/library/audio/index.js | 2 +- blocks/library/button/index.js | 10 +++------ blocks/library/cover-image/index.js | 2 +- blocks/library/embed/index.js | 2 +- blocks/library/heading/index.js | 9 ++++---- blocks/library/image/index.js | 2 +- blocks/library/list/index.js | 8 ++----- blocks/library/paragraph/index.js | 9 +++----- blocks/library/preformatted/index.js | 2 +- blocks/library/pullquote/index.js | 6 +++--- blocks/library/quote/index.js | 6 +++--- blocks/library/table/index.js | 9 +++----- blocks/library/text-columns/index.js | 2 +- blocks/library/verse/index.js | 2 +- blocks/library/video/index.js | 2 +- package-lock.json | 5 ----- package.json | 1 - 22 files changed, 67 insertions(+), 104 deletions(-) diff --git a/blocks/api/simple-dom.js b/blocks/api/simple-dom.js index 2bb86858682fc..9dae20126cf4f 100644 --- a/blocks/api/simple-dom.js +++ b/blocks/api/simple-dom.js @@ -63,11 +63,3 @@ export function applySimpleNodeList( tree, node ) { } } ); } - -export function createHTMLFromSimpleNodeList( tree ) { - const doc = document.implementation.createHTMLDocument( '' ); - - applySimpleNodeList( tree, doc.body ); - - return doc.body.innerHTML; -} diff --git a/blocks/api/test/matchers.js b/blocks/api/test/matchers.js index 2e1312abeebbb..f8adbcb70b13f 100644 --- a/blocks/api/test/matchers.js +++ b/blocks/api/test/matchers.js @@ -11,15 +11,15 @@ import { renderToString } from '@wordpress/element'; /** * Internal dependencies */ -import * as sources from '../matchers'; -import { valueToElement } from '../../editable'; +import Editable from '../../editable'; +import * as matchers from '../matchers'; describe( 'matchers', () => { const html = '

A delicious sundae dessert.

I want it!

The Cook
'; describe( 'children()', () => { it( 'should return a source function', () => { - const source = sources.children(); + const source = matchers.children(); expect( typeof source ).toBe( 'function' ); } ); @@ -27,15 +27,17 @@ describe( 'matchers', () => { it( 'should return HTML equivalent WPElement of matched element', () => { // Assumption here is that we can cleanly convert back and forth // between a string and WPElement representation - const match = parse( html, sources.children() ); + const match = parse( html, matchers.children() ); - expect( renderToString( valueToElement( match ) ) ).toBe( html ); + expect( + renderToString( ) + ).toBe( html ); } ); } ); describe( 'node()', () => { it( 'should return a source function', () => { - const source = sources.node(); + const source = matchers.node(); expect( typeof source ).toBe( 'function' ); } ); @@ -43,27 +45,13 @@ describe( 'matchers', () => { it( 'should return HTML equivalent WPElement of matched element', () => { // Assumption here is that we can cleanly convert back and forth // between a string and WPElement representation - const match = parse( html, sources.node() ); + const match = parse( html, matchers.node() ); expect( - renderToString( valueToElement( [ match ] ) ) + renderToString( ) ).toBe( `${ html }` ); } ); } ); - - describe( 'query', () => { - it( 'should return HTML equivalent WPElement of matched element using selector', () => { - // Assumption here is that we can cleanly convert back and forth - // between a string and WPElement representation - const match = parse( html, sources.query( 'blockquote > p', sources.node( ) ) ); - - expect( - renderToString( valueToElement( match ) ) - ).toBe( - '

A delicious sundae dessert.

I want it!

' - ); - } ); - } ); } ); diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 5d449560556c0..f313f0bfedd9c 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -29,7 +29,7 @@ import { Slot, Fill } from '@wordpress/components'; import './style.scss'; import { rawHandler } from '../api'; import * as matchers from '../api/matchers'; -import { applySimpleNodeList, createHTMLFromSimpleNodeList } from '../api/simple-dom'; +import { applySimpleNodeList } from '../api/simple-dom'; import FormatToolbar from './format-toolbar'; import TinyMCE from './tinymce'; import { pickAriaProps } from './aria'; @@ -82,7 +82,7 @@ const DEFAULT_FORMATS = [ 'bold', 'italic', 'strikethrough', 'link' ]; * @param {Array} value Value to transform * @return {WPElement} Element. */ -export function valueToElement( value ) { +function valueToElement( value ) { if ( ! Array.isArray( value ) ) { return value; } @@ -93,8 +93,19 @@ export function valueToElement( value ) { } const [ type, props, ...children ] = element; + const reactProps = Object.keys( props ).reduce( ( accumulator, key ) => { + const mapping = { + class: 'className', + for: 'htmlFor', + }; + + return { + ...accumulator, + [ mapping[ key ] ? mapping[ key ] : key ]: props[ key ], + }; + }, { key: i } ); - return createElement( type, { ...props, key: i }, ...valueToElement( children ) ); + return createElement( type, { ...reactProps }, ...valueToElement( children ) ); } ); } @@ -871,7 +882,7 @@ export default class Editable extends Component { getSettings={ this.getSettings } onSetup={ this.onSetup } style={ style } - defaultValue={ createHTMLFromSimpleNodeList( value ) } + defaultValue={ valueToElement( value ) } isPlaceholderVisible={ isPlaceholderVisible } aria-label={ placeholder } { ...ariaProps } @@ -901,10 +912,4 @@ Editable.defaultProps = { formatters: [], }; -Editable.Value = ( { tagName: TagName = 'div', value = [], ...props } ) => { - const HTML = createHTMLFromSimpleNodeList( value ); - - return ( - - ); -}; +Editable.Value = ( { value } ) => valueToElement( value ); diff --git a/blocks/editable/test/index.js b/blocks/editable/test/index.js index 70b5d12f587f8..263475300a8aa 100644 --- a/blocks/editable/test/index.js +++ b/blocks/editable/test/index.js @@ -152,7 +152,7 @@ describe( 'Editable', () => { } ); describe( 'Editable.Value', () => { - const Component = ( { value } ) => ( + const MyComponent = ( { value } ) => (
@@ -160,18 +160,18 @@ describe( 'Editable', () => { it( 'should render value containing string', () => { const value = [ 'Hello, Dolly!' ]; - const wrapper = shallow( ); + const wrapper = shallow( ); expect( wrapper.html() ).toBe( '
Hello, Dolly!
' ); } ); it( 'should render value containing a single DOM node', () => { const value = [ - [ 'h1', {}, 'This is a header' ], + [ 'h1', { class: 'my-class' }, 'This is a header' ], ]; - const wrapper = shallow( ); + const wrapper = shallow( ); - expect( wrapper.html() ).toBe( '

This is a header

' ); + expect( wrapper.html() ).toBe( '

This is a header

' ); } ); it( 'should render value with deeply nested DOM nodes', () => { @@ -186,7 +186,7 @@ describe( 'Editable', () => { ] ], '.', ]; - const wrapper = shallow( ); + const wrapper = shallow( ); expect( wrapper.html() ).toBe( '
This is a paragraph with a link with bold and italics.
' diff --git a/blocks/editable/tinymce.js b/blocks/editable/tinymce.js index 5df27e245b0a8..26e762cd72ecb 100644 --- a/blocks/editable/tinymce.js +++ b/blocks/editable/tinymce.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Component, createElement } from '@wordpress/element'; +import { Component, Children, createElement } from '@wordpress/element'; /** * Internal dependencies @@ -105,10 +105,10 @@ export default class TinyMCE extends Component { // If a default value is provided, render it into the DOM even before // TinyMCE finishes initializing. This avoids a short delay by allowing // us to show and focus the content before it's truly ready to edit. - // let children; - // if ( defaultValue ) { - // children = Children.toArray( defaultValue ); - // } + let children; + if ( defaultValue ) { + children = Children.toArray( defaultValue ); + } return createElement( tagName, { ref: ( node ) => this.editorNode = node, @@ -117,7 +117,6 @@ export default class TinyMCE extends Component { className: classnames( className, 'blocks-editable__tinymce' ), style, ...ariaProps, - dangerouslySetInnerHTML: { __html: defaultValue }, - } ); + }, children ); } } diff --git a/blocks/library/audio/index.js b/blocks/library/audio/index.js index 30fc79f32ec9c..903ebe15ad388 100644 --- a/blocks/library/audio/index.js +++ b/blocks/library/audio/index.js @@ -177,7 +177,7 @@ registerBlockType( 'core/audio', { return (
); }, diff --git a/blocks/library/button/index.js b/blocks/library/button/index.js index 1536019ecafdc..b5b5d65f70a63 100644 --- a/blocks/library/button/index.js +++ b/blocks/library/button/index.js @@ -205,13 +205,9 @@ registerBlockType( 'core/button', { return (
- + + +
); }, diff --git a/blocks/library/cover-image/index.js b/blocks/library/cover-image/index.js index ea6086442626c..fb2224afc571d 100644 --- a/blocks/library/cover-image/index.js +++ b/blocks/library/cover-image/index.js @@ -181,7 +181,7 @@ registerBlockType( 'core/cover-image', { return (
- +

); }, diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index fae1598a86737..c5a03b3df6f33 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -234,7 +234,7 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k return (
{ `\n${ url }\n` /* URL needs to be on its own line. */ } - + { caption && caption.length > 0 &&
}
); }, diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index f1ccdb20a71e7..e95a11e6e47ed 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -169,13 +169,12 @@ registerBlockType( 'core/heading', { save( { attributes } ) { const { align, nodeName, content } = attributes; + const Tag = nodeName.toLowerCase(); return ( - + + + ); }, } ); diff --git a/blocks/library/image/index.js b/blocks/library/image/index.js index 8ca20af2984b8..5c5534fc02a95 100644 --- a/blocks/library/image/index.js +++ b/blocks/library/image/index.js @@ -151,7 +151,7 @@ registerBlockType( 'core/image', { return (
{ href ? { image } : image } - + { caption && caption.length > 0 &&
}
); }, diff --git a/blocks/library/list/index.js b/blocks/library/list/index.js index 282a309eaab7f..c3a2834f41d98 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -361,12 +361,8 @@ registerBlockType( 'core/list', { save( { attributes } ) { const { nodeName, values } = attributes; + const Tag = nodeName.toLowerCase(); - return ( - - ); + return ; }, } ); diff --git a/blocks/library/paragraph/index.js b/blocks/library/paragraph/index.js index 761c5777e89e6..dc29e8ad9854e 100644 --- a/blocks/library/paragraph/index.js +++ b/blocks/library/paragraph/index.js @@ -281,12 +281,9 @@ registerBlockType( 'core/paragraph', { }; return ( - +

+ +

); }, } ); diff --git a/blocks/library/preformatted/index.js b/blocks/library/preformatted/index.js index 384bda9218663..b28085a8a9267 100644 --- a/blocks/library/preformatted/index.js +++ b/blocks/library/preformatted/index.js @@ -87,6 +87,6 @@ registerBlockType( 'core/preformatted', { save( { attributes } ) { const { content } = attributes; - return ; + return
; }, } ); diff --git a/blocks/library/pullquote/index.js b/blocks/library/pullquote/index.js index 0a2d91e079fa5..d8e8334c0fff0 100644 --- a/blocks/library/pullquote/index.js +++ b/blocks/library/pullquote/index.js @@ -120,10 +120,10 @@ registerBlockType( 'core/pullquote', { return (
- { value.map( ( [ tagName, , content ], i ) => - + + { citation && citation.length > 0 && ( + ) } -
); }, diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index cade58be9ae1f..197ea44792d64 100644 --- a/blocks/library/quote/index.js +++ b/blocks/library/quote/index.js @@ -227,10 +227,10 @@ registerBlockType( 'core/quote', { className={ style === 2 ? 'is-large' : '' } style={ { textAlign: align ? align : null } } > - { value.map( ( [ tagName, , content ], i ) => - + + { citation && citation.length > 0 && ( + ) } - ); }, diff --git a/blocks/library/table/index.js b/blocks/library/table/index.js index a9abf1806fa03..70b62db1e745c 100644 --- a/blocks/library/table/index.js +++ b/blocks/library/table/index.js @@ -107,13 +107,10 @@ registerBlockType( 'core/table', { save( { attributes } ) { const { content, align } = attributes; - return ( - + + +
); }, } ); diff --git a/blocks/library/text-columns/index.js b/blocks/library/text-columns/index.js index ef939548fa903..5c8b81e064125 100644 --- a/blocks/library/text-columns/index.js +++ b/blocks/library/text-columns/index.js @@ -114,7 +114,7 @@ registerBlockType( 'core/text-columns', {
{ times( columns, ( index ) =>
- +

{ content && content[ index ] && }

) }
diff --git a/blocks/library/verse/index.js b/blocks/library/verse/index.js index 07960cbb29062..61eb412463483 100644 --- a/blocks/library/verse/index.js +++ b/blocks/library/verse/index.js @@ -78,6 +78,6 @@ registerBlockType( 'core/verse', { }, save( { attributes, className } ) { - return ; + return
; }, } ); diff --git a/blocks/library/video/index.js b/blocks/library/video/index.js index b3f07344a6541..8a00be4b06c4e 100644 --- a/blocks/library/video/index.js +++ b/blocks/library/video/index.js @@ -144,7 +144,7 @@ registerBlockType( 'core/video', { return (
{ src &&
); }, diff --git a/package-lock.json b/package-lock.json index d73c5ce0e5323..d4cd9d97290ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2810,11 +2810,6 @@ "isarray": "1.0.0" } }, - "dom-react": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dom-react/-/dom-react-2.2.0.tgz", - "integrity": "sha1-3GJwYI7VbL35DJo+w1U/m1oL17M=" - }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", diff --git a/package.json b/package.json index f136b915cc164..dfe2c609a3580 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "@wordpress/url": "0.1.0-beta.1", "classnames": "2.2.5", "clipboard": "1.7.1", - "dom-react": "2.2.0", "dom-scroll-into-view": "1.2.1", "element-closest": "2.0.2", "escape-string-regexp": "1.0.5",