From 2bfc296b006146f39374552d764a7cf2d4240c37 Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 25 Sep 2017 13:31:34 +0200 Subject: [PATCH 01/11] WIP --- blocks/api/matchers.js | 18 +++++++----- blocks/editable/index.js | 42 ++++++++++++++++++---------- blocks/library/button/index.js | 2 +- blocks/library/cover-image/index.js | 2 +- blocks/library/embed/index.js | 2 +- blocks/library/heading/index.js | 2 +- blocks/library/image/index.js | 3 +- blocks/library/list/index.js | 7 ++--- blocks/library/paragraph/index.js | 6 +++- blocks/library/preformatted/index.js | 2 +- blocks/library/pullquote/index.js | 6 ++-- blocks/library/quote/index.js | 6 ++-- blocks/library/table/index.js | 3 +- blocks/library/text-columns/index.js | 2 +- blocks/library/verse/index.js | 2 +- blocks/library/video/index.js | 3 +- 16 files changed, 62 insertions(+), 46 deletions(-) diff --git a/blocks/api/matchers.js b/blocks/api/matchers.js index 0ccf4cf8d8832b..bc66742a858048 100644 --- a/blocks/api/matchers.js +++ b/blocks/api/matchers.js @@ -1,14 +1,18 @@ -/** - * WordPress dependencies - */ -import { createElement } from '@wordpress/element'; - /** * External dependencies */ import { nodeListToReact, nodeToReact } from 'dom-react'; +import { omit } from 'lodash'; export { attr, prop, html, text, query } from 'hpq'; +function toArray( ...args ) { + return [ toElement( ...args ) ]; +} + +function toElement( type, props, ...children ) { + return [ type, omit( props, 'key' ), ...children ]; +} + export const children = ( selector ) => { return ( domNode ) => { let match = domNode; @@ -18,7 +22,7 @@ export const children = ( selector ) => { } if ( match ) { - return nodeListToReact( match.childNodes || [], createElement ); + return nodeListToReact( match.childNodes || [], toArray ); } return []; @@ -33,6 +37,6 @@ export const node = ( selector ) => { match = domNode.querySelector( selector ); } - return nodeToReact( match, createElement ); + return nodeToReact( match, toElement ); }; }; diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 10de33f38900e7..f988be555d44b0 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -37,7 +37,7 @@ import { EVENTS } from './constants'; const { BACKSPACE, DELETE, ENTER } = keycodes; -function createTinyMCEElement( type, props, ...children ) { +function toArray( type, props, ...children ) { if ( props[ 'data-mce-bogus' ] === 'all' ) { return null; } @@ -46,11 +46,11 @@ function createTinyMCEElement( type, props, ...children ) { return children; } - return createElement( + return [ [ type, - omitBy( props, ( value, key ) => key.indexOf( 'data-mce-' ) === 0 ), - ...children - ); + omitBy( props, ( value, key ) => key.indexOf( 'data-mce-' ) === 0 || key === 'key' ), + ...children, + ] ]; } function isLinkBoundary( fragment ) { @@ -547,8 +547,8 @@ export default class Editable extends Component { const index = dom.nodeIndex( selectedNode ); const beforeNodes = childNodes.slice( 0, index ); const afterNodes = childNodes.slice( index + 1 ); - const beforeElement = nodeListToReact( beforeNodes, createTinyMCEElement ); - const afterElement = nodeListToReact( afterNodes, createTinyMCEElement ); + const beforeElement = nodeListToReact( beforeNodes, toArray ); + const afterElement = nodeListToReact( afterNodes, toArray ); this.setContent( beforeElement ); this.props.onSplit( beforeElement, afterElement ); @@ -602,8 +602,8 @@ export default class Editable extends Component { const beforeFragment = beforeRange.extractContents(); const afterFragment = afterRange.extractContents(); - const beforeElement = nodeListToReact( beforeFragment.childNodes, createTinyMCEElement ); - const afterElement = isLinkBoundary( afterFragment ) ? [] : nodeListToReact( afterFragment.childNodes, createTinyMCEElement ); + const beforeElement = nodeListToReact( beforeFragment.childNodes, toArray ); + const afterElement = isLinkBoundary( afterFragment ) ? [] : nodeListToReact( afterFragment.childNodes, toArray ); this.setContent( beforeElement ); this.props.onSplit( beforeElement, afterElement, ...blocks ); @@ -656,8 +656,8 @@ export default class Editable extends Component { this.setContent( this.props.value ); this.props.onSplit( - nodeListToReact( before, createTinyMCEElement ), - nodeListToReact( after, createTinyMCEElement ) + nodeListToReact( before, toArray ), + nodeListToReact( after, toArray ) ); } @@ -692,12 +692,12 @@ export default class Editable extends Component { content = ''; } - content = renderToString( content ); + content = renderToString( valueToReact( content ) ); this.editor.setContent( content, { format: 'raw' } ); } getContent() { - return nodeListToReact( this.editor.getBody().childNodes || [], createTinyMCEElement ); + return nodeListToReact( this.editor.getBody().childNodes || [], toArray ); } updateFocus() { @@ -850,7 +850,7 @@ export default class Editable extends Component { getSettings={ this.getSettings } onSetup={ this.onSetup } style={ style } - defaultValue={ value } + defaultValue={ valueToReact( value ) } isPlaceholderVisible={ isPlaceholderVisible } aria-label={ placeholder } { ...ariaProps } @@ -879,3 +879,17 @@ Editable.defaultProps = { formattingControls: DEFAULT_FORMATS, formatters: [], }; + +Editable.Value = ( { value } ) => valueToReact( value ); + +function valueToReact( value ) { + return value.map( ( element, i ) => { + if ( typeof element === 'string' ) { + return element; + } + + const [ type, props, ...children ] = element; + + return createElement( type, { ...props, key: i }, ...valueToReact( children ) ); + } ); +} diff --git a/blocks/library/button/index.js b/blocks/library/button/index.js index 46fdf9c1b543dd..b5b5d65f70a63f 100644 --- a/blocks/library/button/index.js +++ b/blocks/library/button/index.js @@ -206,7 +206,7 @@ registerBlockType( 'core/button', { return (
- { text } +
); diff --git a/blocks/library/cover-image/index.js b/blocks/library/cover-image/index.js index 7404a4cb5333c0..fb2224afc571df 100644 --- a/blocks/library/cover-image/index.js +++ b/blocks/library/cover-image/index.js @@ -181,7 +181,7 @@ registerBlockType( 'core/cover-image', { return (
-

{ title }

+

); }, diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 9b53cf9a111164..c5a03b3df6f339 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 &&
{ caption }
} + { caption && caption.length > 0 &&
}
); }, diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index 9fbca6f3c4bdae..9b28842842a928 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -174,7 +174,7 @@ registerBlockType( 'core/heading', { return ( - { content } + ); }, diff --git a/blocks/library/image/index.js b/blocks/library/image/index.js index 4c94d5f26de71b..5c5534fc02a955 100644 --- a/blocks/library/image/index.js +++ b/blocks/library/image/index.js @@ -11,6 +11,7 @@ import './style.scss'; import './editor.scss'; import { registerBlockType, createBlock } from '../../api'; import ImageBlock from './block'; +import Editable from '../../editable'; registerBlockType( 'core/image', { title: __( 'Image' ), @@ -150,7 +151,7 @@ registerBlockType( 'core/image', { return (
{ href ? { image } : image } - { caption && caption.length > 0 &&
{ caption }
} + { caption && caption.length > 0 &&
}
); }, diff --git a/blocks/library/list/index.js b/blocks/library/list/index.js index b136253422fe1a..c3a2834f41d989 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -361,11 +361,8 @@ registerBlockType( 'core/list', { save( { attributes } ) { const { nodeName, values } = attributes; + const Tag = nodeName.toLowerCase(); - return createElement( - nodeName.toLowerCase(), - null, - values - ); + return ; }, } ); diff --git a/blocks/library/paragraph/index.js b/blocks/library/paragraph/index.js index 983661ce524466..adc0d60a125ffc 100644 --- a/blocks/library/paragraph/index.js +++ b/blocks/library/paragraph/index.js @@ -280,7 +280,11 @@ registerBlockType( 'core/paragraph', { textAlign: align, }; - return

{ content }

; + return ( +

+ +

+ ); }, } ); diff --git a/blocks/library/preformatted/index.js b/blocks/library/preformatted/index.js index e5fe21e7a6d6eb..b28085a8a92675 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
{ content }
; + return
; }, } ); diff --git a/blocks/library/pullquote/index.js b/blocks/library/pullquote/index.js index fc55e75ecf0ed5..d8e8334c0fff04 100644 --- a/blocks/library/pullquote/index.js +++ b/blocks/library/pullquote/index.js @@ -120,11 +120,9 @@ registerBlockType( 'core/pullquote', { return (
- { value && value.map( ( paragraph, i ) => -

{ paragraph.children && paragraph.children.props.children }

- ) } + { citation && citation.length > 0 && ( - { citation } + ) }
); diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index 3b7a6a10618499..197ea44792d644 100644 --- a/blocks/library/quote/index.js +++ b/blocks/library/quote/index.js @@ -227,11 +227,9 @@ registerBlockType( 'core/quote', { className={ style === 2 ? 'is-large' : '' } style={ { textAlign: align ? align : null } } > - { value.map( ( paragraph, i ) => ( -

{ paragraph.children && paragraph.children.props.children }

- ) ) } + { citation && citation.length > 0 && ( - { citation } + ) } ); diff --git a/blocks/library/table/index.js b/blocks/library/table/index.js index 861017d695fcfa..df657d5e676dec 100644 --- a/blocks/library/table/index.js +++ b/blocks/library/table/index.js @@ -14,6 +14,7 @@ import BlockControls from '../../block-controls'; import BlockAlignmentToolbar from '../../block-alignment-toolbar'; import InspectorControls from '../../inspector-controls'; import BlockDescription from '../../block-description'; +import Editable from '../../editable'; registerBlockType( 'core/table', { title: __( 'Table' ), @@ -89,7 +90,7 @@ registerBlockType( 'core/table', { const { content, align } = attributes; return ( - { content } +
); }, diff --git a/blocks/library/text-columns/index.js b/blocks/library/text-columns/index.js index a84684c9285e62..3a9e9ad542137a 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 ].children }

+

{ content && }

) }
diff --git a/blocks/library/verse/index.js b/blocks/library/verse/index.js index 7c553121bacb0f..61eb412463483a 100644 --- a/blocks/library/verse/index.js +++ b/blocks/library/verse/index.js @@ -78,6 +78,6 @@ registerBlockType( 'core/verse', { }, save( { attributes, className } ) { - return
{ attributes.content }
; + return
; }, } ); diff --git a/blocks/library/video/index.js b/blocks/library/video/index.js index 427054dbbabb0e..8a00be4b06c4ef 100644 --- a/blocks/library/video/index.js +++ b/blocks/library/video/index.js @@ -142,10 +142,9 @@ registerBlockType( 'core/video', { save( { attributes } ) { const { src, caption, align } = attributes; return ( -
{ src &&
); }, From 7d243fa7f75c30fe341dea65a7cd8f63392b3e29 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 19 Oct 2017 12:27:25 +0200 Subject: [PATCH 02/11] Editable: Add missing Editable.Value wrappers to the existing blocks --- blocks/library/audio/index.js | 2 +- blocks/library/text-columns/index.js | 2 +- docs/blocks-controls.md | 2 +- docs/blocks-editable.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/blocks/library/audio/index.js b/blocks/library/audio/index.js index 19562063157f81..903ebe15ad388f 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/text-columns/index.js b/blocks/library/text-columns/index.js index 3a9e9ad542137a..5c8b81e0641250 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 && content[ index ] && }

) }
diff --git a/docs/blocks-controls.md b/docs/blocks-controls.md index 50d96ce1e3029b..7fb73df0732467 100644 --- a/docs/blocks-controls.md +++ b/docs/blocks-controls.md @@ -143,7 +143,7 @@ registerBlockType( 'gutenberg-boilerplate-esnext/hello-world-step-04', { save( { attributes, className } ) { const { content } = attributes; - return

{ content }

; + return

; }, } ); ``` diff --git a/docs/blocks-editable.md b/docs/blocks-editable.md index 7a5a9ce3fa77e4..a819233bd4260a 100644 --- a/docs/blocks-editable.md +++ b/docs/blocks-editable.md @@ -99,7 +99,7 @@ registerBlockType( 'gutenberg-boilerplate-esnext/hello-world-step-03', { save( { attributes, className } ) { const { content } = attributes; - return

{ content }

; + return

; }, } ); ``` From 0662a94bdcdf7d3f61f80432da9725a0bc732376 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 19 Oct 2017 15:22:13 +0200 Subject: [PATCH 03/11] Editable: Add unit tests to verify Editable.Value --- blocks/editable/index.js | 4 +++ blocks/editable/test/index.js | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/blocks/editable/index.js b/blocks/editable/index.js index f988be555d44b0..2e7c26ed2e62e2 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -883,6 +883,10 @@ Editable.defaultProps = { Editable.Value = ( { value } ) => valueToReact( value ); function valueToReact( value ) { + if ( ! Array.isArray( value ) ) { + return value; + } + return value.map( ( element, i ) => { if ( typeof element === 'string' ) { return element; diff --git a/blocks/editable/test/index.js b/blocks/editable/test/index.js index 8213fbf8e700c6..8d14fcaf65deae 100644 --- a/blocks/editable/test/index.js +++ b/blocks/editable/test/index.js @@ -150,4 +150,52 @@ describe( 'Editable', () => { } ); } ); } ); + + describe( 'Editable.Value', () => { + const Component = ( { value } ) => ( +
+ +
+ ); + + it( 'should render value containing string', () => { + const value = [ 'Hello, Dolly!' ]; + 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' ], + ]; + const wrapper = shallow( ); + + expect( wrapper.html() ).toBe( '

This is a header

' ); + } ); + + it( 'should render value with deeply nested DOM nodes', () => { + const value = [ + 'This is a ', + [ 'strong', {}, 'paragraph', ], + ' with a ', + [ 'a', { href: 'https://w.org/' }, 'link with ', [ + 'b', + {}, + 'bold ', + [ + 'i', + {}, + 'and italics', + ], + ] ], + '.', + ]; + const wrapper = shallow( ); + + expect( wrapper.html() ).toBe( + '
This is a paragraph with a link with bold and italics.
' + ); + } ); + } ); } ); From 2a0611e2dce046c30517a315a3d1f622d54ef5ec Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 23 Oct 2017 13:44:56 +0200 Subject: [PATCH 04/11] Testing: Regenerate test fixtures for full post content checks --- .../test/fixtures/core__heading__h2-em.json | 9 +- blocks/test/fixtures/core__list__ul.json | 67 ++-- blocks/test/fixtures/core__preformatted.json | 16 +- blocks/test/fixtures/core__pullquote.json | 17 +- .../core__pullquote__multi-paragraph.json | 51 +-- .../test/fixtures/core__quote__style-1.json | 17 +- .../test/fixtures/core__quote__style-2.json | 17 +- blocks/test/fixtures/core__table.json | 360 +++++++++--------- .../core__text__converts-to-paragraph.json | 9 +- blocks/test/fixtures/core__verse.json | 16 +- 10 files changed, 280 insertions(+), 299 deletions(-) diff --git a/blocks/test/fixtures/core__heading__h2-em.json b/blocks/test/fixtures/core__heading__h2-em.json index 39674931b4429a..2f6af6a1afcf5d 100644 --- a/blocks/test/fixtures/core__heading__h2-em.json +++ b/blocks/test/fixtures/core__heading__h2-em.json @@ -6,10 +6,11 @@ "attributes": { "content": [ "The ", - { - "type": "em", - "children": "Inserter" - }, + [ + "em", + {}, + "Inserter" + ], " Tool" ], "nodeName": "H2" diff --git a/blocks/test/fixtures/core__list__ul.json b/blocks/test/fixtures/core__list__ul.json index 15bc029cf8de16..9e03274c49e4a2 100644 --- a/blocks/test/fixtures/core__list__ul.json +++ b/blocks/test/fixtures/core__list__ul.json @@ -6,37 +6,42 @@ "attributes": { "nodeName": "UL", "values": [ - { - "type": "li", - "children": "Text & Headings" - }, - { - "type": "li", - "children": "Images & Videos" - }, - { - "type": "li", - "children": "Galleries" - }, - { - "type": "li", - "children": "Embeds, like YouTube, Tweets, or other WordPress posts." - }, - { - "type": "li", - "children": "Layout blocks, like Buttons, Hero Images, Separators, etc." - }, - { - "type": "li", - "children": [ - "And ", - { - "type": "em", - "children": "Lists" - }, - " like this one of course :)" - ] - } + [ + "li", + {}, + "Text & Headings" + ], + [ + "li", + {}, + "Images & Videos" + ], + [ + "li", + {}, + "Galleries" + ], + [ + "li", + {}, + "Embeds, like YouTube, Tweets, or other WordPress posts." + ], + [ + "li", + {}, + "Layout blocks, like Buttons, Hero Images, Separators, etc." + ], + [ + "li", + {}, + "And ", + [ + "em", + {}, + "Lists" + ], + " like this one of course :)" + ] ] }, "originalContent": "
  • Text & Headings
  • Images & Videos
  • Galleries
  • Embeds, like YouTube, Tweets, or other WordPress posts.
  • Layout blocks, like Buttons, Hero Images, Separators, etc.
  • And Lists like this one of course :)
" diff --git a/blocks/test/fixtures/core__preformatted.json b/blocks/test/fixtures/core__preformatted.json index 37ca66e8c95ad5..a3bbb9daac74ec 100644 --- a/blocks/test/fixtures/core__preformatted.json +++ b/blocks/test/fixtures/core__preformatted.json @@ -6,14 +6,16 @@ "attributes": { "content": [ "Some ", - { - "type": "em", - "children": "preformatted" - }, + [ + "em", + {}, + "preformatted" + ], " text...", - { - "type": "br" - }, + [ + "br", + {} + ], "And more!" ] }, diff --git a/blocks/test/fixtures/core__pullquote.json b/blocks/test/fixtures/core__pullquote.json index 5ebe0b5564fb25..f0235d70916cfd 100644 --- a/blocks/test/fixtures/core__pullquote.json +++ b/blocks/test/fixtures/core__pullquote.json @@ -5,18 +5,11 @@ "isValid": true, "attributes": { "value": [ - { - "children": { - "type": "p", - "key": null, - "ref": null, - "props": { - "children": "Testing pullquote block..." - }, - "_owner": null, - "_store": {} - } - } + [ + "p", + {}, + "Testing pullquote block..." + ] ], "citation": [ "...with a caption" diff --git a/blocks/test/fixtures/core__pullquote__multi-paragraph.json b/blocks/test/fixtures/core__pullquote__multi-paragraph.json index 29eed74d38b3b5..520b982dd6c0b6 100644 --- a/blocks/test/fixtures/core__pullquote__multi-paragraph.json +++ b/blocks/test/fixtures/core__pullquote__multi-paragraph.json @@ -2,45 +2,22 @@ { "uid": "_uid_0", "name": "core/pullquote", - "isValid": true, + "isValid": false, "attributes": { "value": [ - { - "children": { - "type": "p", - "key": null, - "ref": null, - "props": { - "children": [ - "Paragraph ", - { - "type": "strong", - "key": "_domReact68", - "ref": null, - "props": { - "children": "one" - }, - "_owner": null, - "_store": {} - } - ] - }, - "_owner": null, - "_store": {} - } - }, - { - "children": { - "type": "p", - "key": null, - "ref": null, - "props": { - "children": "Paragraph two" - }, - "_owner": null, - "_store": {} - } - } + [ + "p", + {}, + "Paragraph ", + "strong", + {}, + "one" + ], + [ + "p", + {}, + "Paragraph two" + ] ], "citation": [ "by whomever" diff --git a/blocks/test/fixtures/core__quote__style-1.json b/blocks/test/fixtures/core__quote__style-1.json index bea152f89f32c6..7f048eb1c35fc4 100644 --- a/blocks/test/fixtures/core__quote__style-1.json +++ b/blocks/test/fixtures/core__quote__style-1.json @@ -5,18 +5,11 @@ "isValid": true, "attributes": { "value": [ - { - "children": { - "type": "p", - "key": null, - "ref": null, - "props": { - "children": "The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery." - }, - "_owner": null, - "_store": {} - } - } + [ + "p", + {}, + "The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery." + ] ], "citation": [ "Matt Mullenweg, 2017" diff --git a/blocks/test/fixtures/core__quote__style-2.json b/blocks/test/fixtures/core__quote__style-2.json index ea48f03aef42fe..e5daf2ff8b5197 100644 --- a/blocks/test/fixtures/core__quote__style-2.json +++ b/blocks/test/fixtures/core__quote__style-2.json @@ -5,18 +5,11 @@ "isValid": true, "attributes": { "value": [ - { - "children": { - "type": "p", - "key": null, - "ref": null, - "props": { - "children": "There is no greater agony than bearing an untold story inside you." - }, - "_owner": null, - "_store": {} - } - } + [ + "p", + {}, + "There is no greater agony than bearing an untold story inside you." + ] ], "citation": [ "Maya Angelou" diff --git a/blocks/test/fixtures/core__table.json b/blocks/test/fixtures/core__table.json index 2ecdee94dd749c..dfb3610bb2c990 100644 --- a/blocks/test/fixtures/core__table.json +++ b/blocks/test/fixtures/core__table.json @@ -5,195 +5,209 @@ "isValid": true, "attributes": { "content": [ - { - "type": "thead", - "children": { - "type": "tr", - "children": [ - { - "type": "th", - "children": "Version" - }, - { - "type": "th", - "children": "Musician" - }, - { - "type": "th", - "children": "Date" - } + [ + "thead", + {}, + [ + "tr", + {}, + [ + "th", + {}, + "Version" + ], + [ + "th", + {}, + "Musician" + ], + [ + "th", + {}, + "Date" ] - } - }, - { - "type": "tbody", - "children": [ - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2003/05/wordpress-now-available/" - }, - "children": ".70" - } - }, - { - "type": "td", - "children": "No musician chosen." + ] + ], + [ + "tbody", + {}, + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2003/05/wordpress-now-available/" }, - { - "type": "td", - "children": "May 27, 2003" - } + ".70" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2004/01/wordpress-10/" - }, - "children": "1.0" - } - }, - { - "type": "td", - "children": "Miles Davis" + ], + [ + "td", + {}, + "No musician chosen." + ], + [ + "td", + {}, + "May 27, 2003" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2004/01/wordpress-10/" }, - { - "type": "td", - "children": "January 3, 2004" - } + "1.0" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": [ - "Lots of versions skipped, see ", - { - "type": "a", - "attributes": { - "href": "https://codex.wordpress.org/WordPress_Versions" - }, - "children": "the full list" - } - ] - }, - { - "type": "td", - "children": "…" + ], + [ + "td", + {}, + "Miles Davis" + ], + [ + "td", + {}, + "January 3, 2004" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + "Lots of versions skipped, see ", + [ + "a", + { + "href": "https://codex.wordpress.org/WordPress_Versions" }, - { - "type": "td", - "children": "…" - } + "the full list" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2015/12/clifford/" - }, - "children": "4.4" - } - }, - { - "type": "td", - "children": "Clifford Brown" + ], + [ + "td", + {}, + "…" + ], + [ + "td", + {}, + "…" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2015/12/clifford/" }, - { - "type": "td", - "children": "December 8, 2015" - } + "4.4" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2016/04/coleman/" - }, - "children": "4.5" - } - }, - { - "type": "td", - "children": "Coleman Hawkins" + ], + [ + "td", + {}, + "Clifford Brown" + ], + [ + "td", + {}, + "December 8, 2015" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2016/04/coleman/" }, - { - "type": "td", - "children": "April 12, 2016" - } + "4.5" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2016/08/pepper/" - }, - "children": "4.6" - } - }, - { - "type": "td", - "children": "Pepper Adams" + ], + [ + "td", + {}, + "Coleman Hawkins" + ], + [ + "td", + {}, + "April 12, 2016" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2016/08/pepper/" }, - { - "type": "td", - "children": "August 16, 2016" - } + "4.6" ] - }, - { - "type": "tr", - "children": [ - { - "type": "td", - "children": { - "type": "a", - "attributes": { - "href": "https://wordpress.org/news/2016/12/vaughan/" - }, - "children": "4.7" - } - }, - { - "type": "td", - "children": "Sarah Vaughan" + ], + [ + "td", + {}, + "Pepper Adams" + ], + [ + "td", + {}, + "August 16, 2016" + ] + ], + [ + "tr", + {}, + [ + "td", + {}, + [ + "a", + { + "href": "https://wordpress.org/news/2016/12/vaughan/" }, - { - "type": "td", - "children": "December 6, 2016" - } + "4.7" ] - } + ], + [ + "td", + {}, + "Sarah Vaughan" + ], + [ + "td", + {}, + "December 6, 2016" + ] ] - } + ] ] }, "originalContent": "
VersionMusicianDate
.70No musician chosen.May 27, 2003
1.0Miles DavisJanuary 3, 2004
Lots of versions skipped, see the full list
4.4Clifford BrownDecember 8, 2015
4.5Coleman HawkinsApril 12, 2016
4.6Pepper AdamsAugust 16, 2016
4.7Sarah VaughanDecember 6, 2016
" diff --git a/blocks/test/fixtures/core__text__converts-to-paragraph.json b/blocks/test/fixtures/core__text__converts-to-paragraph.json index 0efed063a93be2..684fd2f9db6b31 100644 --- a/blocks/test/fixtures/core__text__converts-to-paragraph.json +++ b/blocks/test/fixtures/core__text__converts-to-paragraph.json @@ -6,10 +6,11 @@ "attributes": { "content": [ "This is an old-style text block. Changed to ", - { - "type": "code", - "children": "paragraph" - }, + [ + "code", + {}, + "paragraph" + ], " in #2135." ], "dropCap": false diff --git a/blocks/test/fixtures/core__verse.json b/blocks/test/fixtures/core__verse.json index 0baa254be043a9..4633bbe53681b5 100644 --- a/blocks/test/fixtures/core__verse.json +++ b/blocks/test/fixtures/core__verse.json @@ -6,14 +6,16 @@ "attributes": { "content": [ "A ", - { - "type": "em", - "children": "verse" - }, + [ + "em", + {}, + "verse" + ], "…", - { - "type": "br" - }, + [ + "br", + {} + ], "And more!" ] }, From 2a1989c05b2dd1b3297bbfb2bbf158d3385bb40f Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 23 Oct 2017 16:35:47 +0200 Subject: [PATCH 05/11] Testing: Fix failing tests caused by the node matcher --- blocks/api/test/matchers.js | 9 +++---- blocks/editable/index.js | 44 ++++++++++++++++++++--------------- blocks/editable/test/index.js | 2 +- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/blocks/api/test/matchers.js b/blocks/api/test/matchers.js index 32d1246a2e9d6e..52d2986f9b0341 100644 --- a/blocks/api/test/matchers.js +++ b/blocks/api/test/matchers.js @@ -12,6 +12,7 @@ import { renderToString } from '@wordpress/element'; * Internal dependencies */ import * as sources from '../matchers'; +import { valueToElement } from '../../editable'; describe( 'matchers', () => { describe( 'children()', () => { @@ -24,10 +25,10 @@ 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 html = '

A delicious sundae dessert

'; + const html = '

A delicious sundae dessert.

I want it!

'; const match = parse( html, sources.children() ); - expect( renderToString( match ) ).toBe( html ); + expect( renderToString( valueToElement( match ) ) ).toBe( html ); } ); } ); @@ -41,10 +42,10 @@ 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 html = '

A delicious sundae dessert

'; + const html = '

A delicious sundae dessert.

'; const match = parse( html, sources.node() ); - expect( renderToString( match ) ).toBe( `${ html }` ); + expect( renderToString( valueToElement( [ match ] ) ) ).toBe( `${ html }` ); } ); } ); } ); diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 2e7c26ed2e62e2..06856f9eb798a0 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -72,6 +72,28 @@ function getFormatProperties( formatName, parents ) { const DEFAULT_FORMATS = [ 'bold', 'italic', 'strikethrough', 'link' ]; +/** + * Transforms internal block's representation into an Element. + * + * @param {Array} value Value to transform + * @return {WPElement} Element. + */ +export function valueToElement( value ) { + if ( ! Array.isArray( value ) ) { + return value; + } + + return value.map( ( element, i ) => { + if ( typeof element === 'string' ) { + return element; + } + + const [ type, props, ...children ] = element; + + return createElement( type, { ...props, key: i }, ...valueToElement( children ) ); + } ); +} + export default class Editable extends Component { constructor( props ) { super( ...arguments ); @@ -692,7 +714,7 @@ export default class Editable extends Component { content = ''; } - content = renderToString( valueToReact( content ) ); + content = renderToString( valueToElement( content ) ); this.editor.setContent( content, { format: 'raw' } ); } @@ -850,7 +872,7 @@ export default class Editable extends Component { getSettings={ this.getSettings } onSetup={ this.onSetup } style={ style } - defaultValue={ valueToReact( value ) } + defaultValue={ valueToElement( value ) } isPlaceholderVisible={ isPlaceholderVisible } aria-label={ placeholder } { ...ariaProps } @@ -880,20 +902,4 @@ Editable.defaultProps = { formatters: [], }; -Editable.Value = ( { value } ) => valueToReact( value ); - -function valueToReact( value ) { - if ( ! Array.isArray( value ) ) { - return value; - } - - return value.map( ( element, i ) => { - if ( typeof element === 'string' ) { - return element; - } - - const [ type, props, ...children ] = element; - - return createElement( type, { ...props, key: i }, ...valueToReact( children ) ); - } ); -} +Editable.Value = ( { value } ) => valueToElement( value ); diff --git a/blocks/editable/test/index.js b/blocks/editable/test/index.js index 8d14fcaf65deae..711869f552e4e3 100644 --- a/blocks/editable/test/index.js +++ b/blocks/editable/test/index.js @@ -177,7 +177,7 @@ describe( 'Editable', () => { it( 'should render value with deeply nested DOM nodes', () => { const value = [ 'This is a ', - [ 'strong', {}, 'paragraph', ], + [ 'strong', {}, 'paragraph' ], ' with a ', [ 'a', { href: 'https://w.org/' }, 'link with ', [ 'b', From 54d76311abc1d8fbe520a5b8b37c7cefdadc51c3 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 24 Oct 2017 09:46:42 +0200 Subject: [PATCH 06/11] Framework: Final touches to allow saving blocks state as a tree --- blocks/api/matchers.js | 12 +++------ blocks/api/test/matchers.js | 24 ++++++++++++++--- blocks/editable/test/index.js | 9 ++----- blocks/library/table/index.js | 27 ++++++++++++++++--- .../core__pullquote__multi-paragraph.json | 10 ++++--- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/blocks/api/matchers.js b/blocks/api/matchers.js index bc66742a858048..bcbcfa2cffd2c6 100644 --- a/blocks/api/matchers.js +++ b/blocks/api/matchers.js @@ -2,15 +2,11 @@ * External dependencies */ import { nodeListToReact, nodeToReact } from 'dom-react'; -import { omit } from 'lodash'; +import { flatten, omit } from 'lodash'; export { attr, prop, html, text, query } from 'hpq'; -function toArray( ...args ) { - return [ toElement( ...args ) ]; -} - -function toElement( type, props, ...children ) { - return [ type, omit( props, 'key' ), ...children ]; +function toArray( type, props, ...children ) { + return [ [ type, omit( props, 'key' ), ...children ] ]; } export const children = ( selector ) => { @@ -37,6 +33,6 @@ export const node = ( selector ) => { match = domNode.querySelector( selector ); } - return nodeToReact( match, toElement ); + return flatten( nodeToReact( match, toArray ) ); }; }; diff --git a/blocks/api/test/matchers.js b/blocks/api/test/matchers.js index 52d2986f9b0341..0c6d3250026b80 100644 --- a/blocks/api/test/matchers.js +++ b/blocks/api/test/matchers.js @@ -15,6 +15,8 @@ import * as sources from '../matchers'; import { valueToElement } from '../../editable'; 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(); @@ -25,7 +27,6 @@ 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 html = '

A delicious sundae dessert.

I want it!

'; const match = parse( html, sources.children() ); expect( renderToString( valueToElement( match ) ) ).toBe( html ); @@ -42,10 +43,27 @@ 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 html = '

A delicious sundae dessert.

'; const match = parse( html, sources.node() ); - expect( renderToString( valueToElement( [ match ] ) ) ).toBe( `${ html }` ); + expect( + renderToString( valueToElement( [ match ] ) ) + ).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/test/index.js b/blocks/editable/test/index.js index 711869f552e4e3..70b5d12f587f85 100644 --- a/blocks/editable/test/index.js +++ b/blocks/editable/test/index.js @@ -180,13 +180,8 @@ describe( 'Editable', () => { [ 'strong', {}, 'paragraph' ], ' with a ', [ 'a', { href: 'https://w.org/' }, 'link with ', [ - 'b', - {}, - 'bold ', - [ - 'i', - {}, - 'and italics', + 'b', {}, 'bold ', [ + 'i', {}, 'and italics', ], ] ], '.', diff --git a/blocks/library/table/index.js b/blocks/library/table/index.js index df657d5e676dec..70b62db1e745ca 100644 --- a/blocks/library/table/index.js +++ b/blocks/library/table/index.js @@ -27,10 +27,29 @@ registerBlockType( 'core/table', { source: 'children', selector: 'table', default: [ - -

-

- , + [ + 'tbody', {}, [ + 'tr', {}, [ + 'td', {}, [ + 'br', {}, + ], + ], [ + 'td', {}, [ + 'br', {}, + ], + ], + ], [ + 'tr', {}, [ + 'td', {}, [ + 'br', {}, + ], + ], [ + 'td', {}, [ + 'br', {}, + ], + ], + ], + ], ], }, align: { diff --git a/blocks/test/fixtures/core__pullquote__multi-paragraph.json b/blocks/test/fixtures/core__pullquote__multi-paragraph.json index 520b982dd6c0b6..6e0e4e3d45e45d 100644 --- a/blocks/test/fixtures/core__pullquote__multi-paragraph.json +++ b/blocks/test/fixtures/core__pullquote__multi-paragraph.json @@ -2,16 +2,18 @@ { "uid": "_uid_0", "name": "core/pullquote", - "isValid": false, + "isValid": true, "attributes": { "value": [ [ "p", {}, "Paragraph ", - "strong", - {}, - "one" + [ + "strong", + {}, + "one" + ] ], [ "p", From e50084a117d0ab10ba78d6309e7dc9bc8a4d5f1b Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 30 Oct 2017 18:02:44 +0100 Subject: [PATCH 07/11] Fix eslint error --- blocks/api/test/matchers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blocks/api/test/matchers.js b/blocks/api/test/matchers.js index 0c6d3250026b80..2e1312abeebbb8 100644 --- a/blocks/api/test/matchers.js +++ b/blocks/api/test/matchers.js @@ -60,8 +60,8 @@ describe( 'matchers', () => { const match = parse( html, sources.query( 'blockquote > p', sources.node( ) ) ); expect( - renderToString( valueToElement( match ) - ) ).toBe( + renderToString( valueToElement( match ) ) + ).toBe( '

A delicious sundae dessert.

I want it!

' ); } ); From 7177a6de97b31ef164e3f71bf84a52a333e234fc Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 30 Oct 2017 18:07:35 +0100 Subject: [PATCH 08/11] Fix docs --- docs/blocks-controls.md | 2 +- docs/blocks-editable.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/blocks-controls.md b/docs/blocks-controls.md index 7fb73df0732467..fb1196e17f8a33 100644 --- a/docs/blocks-controls.md +++ b/docs/blocks-controls.md @@ -143,7 +143,7 @@ registerBlockType( 'gutenberg-boilerplate-esnext/hello-world-step-04', { save( { attributes, className } ) { const { content } = attributes; - return

; + return

; }, } ); ``` diff --git a/docs/blocks-editable.md b/docs/blocks-editable.md index a819233bd4260a..334dedda56b56e 100644 --- a/docs/blocks-editable.md +++ b/docs/blocks-editable.md @@ -99,7 +99,7 @@ registerBlockType( 'gutenberg-boilerplate-esnext/hello-world-step-03', { save( { attributes, className } ) { const { content } = attributes; - return

; + return

; }, } ); ``` From 9dab041db59498d726e62224996a337b6e69e91a Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 31 Oct 2017 13:38:48 +0100 Subject: [PATCH 09/11] Try without dom-react --- blocks/api/matchers.js | 17 ++++---- blocks/api/simple-dom.js | 65 +++++++++++++++++++++++++++++++ blocks/editable/index.js | 37 +++++++++--------- blocks/library/heading/index.js | 3 +- blocks/library/paragraph/index.js | 4 +- 5 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 blocks/api/simple-dom.js diff --git a/blocks/api/matchers.js b/blocks/api/matchers.js index bcbcfa2cffd2c6..bc9239f495b387 100644 --- a/blocks/api/matchers.js +++ b/blocks/api/matchers.js @@ -1,15 +1,14 @@ /** * External dependencies */ -import { nodeListToReact, nodeToReact } from 'dom-react'; -import { flatten, omit } from 'lodash'; export { attr, prop, html, text, query } from 'hpq'; -function toArray( type, props, ...children ) { - return [ [ type, omit( props, 'key' ), ...children ] ]; -} +/** + * Internal dependencies + */ +import { createSimpleNode, createSimpleNodeList } from './simple-dom'; -export const children = ( selector ) => { +export const children = ( selector, filter ) => { return ( domNode ) => { let match = domNode; @@ -18,14 +17,14 @@ export const children = ( selector ) => { } if ( match ) { - return nodeListToReact( match.childNodes || [], toArray ); + return createSimpleNodeList( match.childNodes || [], filter ); } return []; }; }; -export const node = ( selector ) => { +export const node = ( selector, filter ) => { return ( domNode ) => { let match = domNode; @@ -33,6 +32,6 @@ export const node = ( selector ) => { match = domNode.querySelector( selector ); } - return flatten( nodeToReact( match, toArray ) ); + return createSimpleNode( match, filter ); }; }; diff --git a/blocks/api/simple-dom.js b/blocks/api/simple-dom.js new file mode 100644 index 00000000000000..9dae20126cf4f8 --- /dev/null +++ b/blocks/api/simple-dom.js @@ -0,0 +1,65 @@ +/** + * External dependencies + */ +import { forEach } from 'lodash'; + +export function createSimpleNode( node, filter = Array ) { + if ( ! node ) { + return null; + } + + if ( node.nodeType === 3 ) { + return node.nodeValue; + } + + if ( node.nodeType !== 1 ) { + return null; + } + + return filter( + node.nodeName.toLowerCase(), + Array.from( node.attributes || [] ).reduce( ( acc, { name, value } ) => ( { + ...acc, + [ name ]: value, + } ), {} ), + ...createSimpleNodeList( node.childNodes || [], filter ) + ); +} + +export function createSimpleNodeList( nodeList, filter ) { + return Array.from( nodeList ).reduce( ( acc, node ) => { + const child = createSimpleNode( node, filter ); + + if ( Array.isArray( child ) && typeof child[ 0 ] !== 'string' ) { + acc.push( ...child ); + } else if ( child ) { + acc.push( child ); + } + + return acc; + }, [] ); +} + +// Smarter application in the future? +export function applySimpleNodeList( tree, node ) { + while ( node.firstChild ) { + node.removeChild( node.firstChild ); + } + + forEach( tree, ( piece ) => { + if ( typeof piece === 'string' ) { + node.appendChild( document.createTextNode( piece ) ); + } else { + const [ name, attributes, ...children ] = piece; + const element = document.createElement( name ); + + forEach( attributes, ( value, key ) => { + element.setAttribute( key, value ); + } ); + + applySimpleNodeList( children, element ); + + node.appendChild( element ); + } + } ); +} diff --git a/blocks/editable/index.js b/blocks/editable/index.js index 06856f9eb798a0..363edbbc1ef0ce 100644 --- a/blocks/editable/index.js +++ b/blocks/editable/index.js @@ -14,13 +14,12 @@ import { defer, noop, } from 'lodash'; -import { nodeListToReact } from 'dom-react'; import 'element-closest'; /** * WordPress dependencies */ -import { createElement, Component, renderToString } from '@wordpress/element'; +import { createElement, Component } from '@wordpress/element'; import { keycodes, createBlobURL } from '@wordpress/utils'; import { Slot, Fill } from '@wordpress/components'; @@ -29,6 +28,8 @@ import { Slot, Fill } from '@wordpress/components'; */ import './style.scss'; import { rawHandler } from '../api'; +import * as matchers from '../api/matchers'; +import { applySimpleNodeList } from '../api/simple-dom'; import FormatToolbar from './format-toolbar'; import TinyMCE from './tinymce'; import { pickAriaProps } from './aria'; @@ -37,7 +38,10 @@ import { EVENTS } from './constants'; const { BACKSPACE, DELETE, ENTER } = keycodes; -function toArray( type, props, ...children ) { +const createNode = matchers.node( null, nodeFilter ); +const createChildren = matchers.children( null, nodeFilter ); + +function nodeFilter( type, props, ...children ) { if ( props[ 'data-mce-bogus' ] === 'all' ) { return null; } @@ -46,11 +50,11 @@ function toArray( type, props, ...children ) { return children; } - return [ [ + return [ type, omitBy( props, ( value, key ) => key.indexOf( 'data-mce-' ) === 0 || key === 'key' ), ...children, - ] ]; + ]; } function isLinkBoundary( fragment ) { @@ -569,8 +573,8 @@ export default class Editable extends Component { const index = dom.nodeIndex( selectedNode ); const beforeNodes = childNodes.slice( 0, index ); const afterNodes = childNodes.slice( index + 1 ); - const beforeElement = nodeListToReact( beforeNodes, toArray ); - const afterElement = nodeListToReact( afterNodes, toArray ); + const beforeElement = beforeNodes.map( createNode ); + const afterElement = afterNodes.map( createNode ); this.setContent( beforeElement ); this.props.onSplit( beforeElement, afterElement ); @@ -624,8 +628,8 @@ export default class Editable extends Component { const beforeFragment = beforeRange.extractContents(); const afterFragment = afterRange.extractContents(); - const beforeElement = nodeListToReact( beforeFragment.childNodes, toArray ); - const afterElement = isLinkBoundary( afterFragment ) ? [] : nodeListToReact( afterFragment.childNodes, toArray ); + const beforeElement = createChildren( beforeFragment ); + const afterElement = isLinkBoundary( afterFragment ) ? [] : createChildren( afterFragment ); this.setContent( beforeElement ); this.props.onSplit( beforeElement, afterElement, ...blocks ); @@ -678,8 +682,8 @@ export default class Editable extends Component { this.setContent( this.props.value ); this.props.onSplit( - nodeListToReact( before, toArray ), - nodeListToReact( after, toArray ) + before.map( createNode ), + after.map( createNode ) ); } @@ -709,17 +713,12 @@ export default class Editable extends Component { this.editor.save(); } - setContent( content ) { - if ( ! content ) { - content = ''; - } - - content = renderToString( valueToElement( content ) ); - this.editor.setContent( content, { format: 'raw' } ); + setContent( content = [] ) { + applySimpleNodeList( content, this.editor.getBody() ); } getContent() { - return nodeListToReact( this.editor.getBody().childNodes || [], toArray ); + return createChildren( this.editor.getBody() ); } updateFocus() { diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index 9b28842842a928..e95a11e6e47ed1 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -2,7 +2,6 @@ * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { concatChildren } from '@wordpress/element'; import { Toolbar } from '@wordpress/components'; /** @@ -94,7 +93,7 @@ registerBlockType( 'core/heading', { merge( attributes, attributesToMerge ) { return { - content: concatChildren( attributes.content, attributesToMerge.content ), + content: [ ...attributes.content, ...attributesToMerge.content ], }; }, diff --git a/blocks/library/paragraph/index.js b/blocks/library/paragraph/index.js index adc0d60a125ffc..dc29e8ad9854e4 100644 --- a/blocks/library/paragraph/index.js +++ b/blocks/library/paragraph/index.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { concatChildren, Component } from '@wordpress/element'; +import { Component } from '@wordpress/element'; import { Autocomplete, PanelBody, PanelColor, withFallbackStyles } from '@wordpress/components'; /** @@ -253,7 +253,7 @@ registerBlockType( 'core/paragraph', { merge( attributes, attributesToMerge ) { return { - content: concatChildren( attributes.content, attributesToMerge.content ), + content: [ ...attributes.content, ...attributesToMerge.content ], }; }, From df23eea54bcebd85bb4f5fbc6427c2b44d43ed04 Mon Sep 17 00:00:00 2001 From: iseulde Date: Fri, 3 Nov 2017 12:16:54 +0100 Subject: [PATCH 10/11] WIP --- blocks/api/simple-dom.js | 8 ++++++++ blocks/editable/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 +- 18 files changed, 68 insertions(+), 38 deletions(-) diff --git a/blocks/api/simple-dom.js b/blocks/api/simple-dom.js index 9dae20126cf4f8..2bb86858682fcd 100644 --- a/blocks/api/simple-dom.js +++ b/blocks/api/simple-dom.js @@ -63,3 +63,11 @@ 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/editable/index.js b/blocks/editable/index.js index 363edbbc1ef0ce..5d449560556c0b 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 } from '../api/simple-dom'; +import { applySimpleNodeList, createHTMLFromSimpleNodeList } from '../api/simple-dom'; import FormatToolbar from './format-toolbar'; import TinyMCE from './tinymce'; import { pickAriaProps } from './aria'; @@ -871,7 +871,7 @@ export default class Editable extends Component { getSettings={ this.getSettings } onSetup={ this.onSetup } style={ style } - defaultValue={ valueToElement( value ) } + defaultValue={ createHTMLFromSimpleNodeList( value ) } isPlaceholderVisible={ isPlaceholderVisible } aria-label={ placeholder } { ...ariaProps } @@ -901,4 +901,10 @@ Editable.defaultProps = { formatters: [], }; -Editable.Value = ( { value } ) => valueToElement( value ); +Editable.Value = ( { tagName: TagName = 'div', value = [], ...props } ) => { + const HTML = createHTMLFromSimpleNodeList( value ); + + return ( + + ); +}; diff --git a/blocks/editable/tinymce.js b/blocks/editable/tinymce.js index 26e762cd72ecba..5df27e245b0a89 100644 --- a/blocks/editable/tinymce.js +++ b/blocks/editable/tinymce.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Component, Children, createElement } from '@wordpress/element'; +import { Component, 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,6 +117,7 @@ export default class TinyMCE extends Component { className: classnames( className, 'blocks-editable__tinymce' ), style, ...ariaProps, - }, children ); + dangerouslySetInnerHTML: { __html: defaultValue }, + } ); } } diff --git a/blocks/library/audio/index.js b/blocks/library/audio/index.js index 903ebe15ad388f..30fc79f32ec9cc 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 b5b5d65f70a63f..1536019ecafdc6 100644 --- a/blocks/library/button/index.js +++ b/blocks/library/button/index.js @@ -205,9 +205,13 @@ registerBlockType( 'core/button', { return (
- - - +
); }, diff --git a/blocks/library/cover-image/index.js b/blocks/library/cover-image/index.js index fb2224afc571df..ea6086442626c6 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 c5a03b3df6f339..fae1598a867377 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 e95a11e6e47ed1..f1ccdb20a71e79 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -169,12 +169,13 @@ 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 5c5534fc02a955..8ca20af2984b81 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 c3a2834f41d989..282a309eaab7fe 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -361,8 +361,12 @@ 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 dc29e8ad9854e4..761c5777e89e63 100644 --- a/blocks/library/paragraph/index.js +++ b/blocks/library/paragraph/index.js @@ -281,9 +281,12 @@ registerBlockType( 'core/paragraph', { }; return ( -

- -

+ ); }, } ); diff --git a/blocks/library/preformatted/index.js b/blocks/library/preformatted/index.js index b28085a8a92675..384bda9218663b 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 d8e8334c0fff04..0a2d91e079fa54 100644 --- a/blocks/library/pullquote/index.js +++ b/blocks/library/pullquote/index.js @@ -120,10 +120,10 @@ registerBlockType( 'core/pullquote', { return (
- - { citation && citation.length > 0 && ( - + { value.map( ( [ tagName, , content ], i ) => + ) } +
); }, diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index 197ea44792d644..cade58be9ae1fe 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 } } > - - { citation && citation.length > 0 && ( - + { value.map( ( [ tagName, , content ], i ) => + ) } + ); }, diff --git a/blocks/library/table/index.js b/blocks/library/table/index.js index 70b62db1e745ca..a9abf1806fa033 100644 --- a/blocks/library/table/index.js +++ b/blocks/library/table/index.js @@ -107,10 +107,13 @@ 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 5c8b81e0641250..ef939548fa903a 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 61eb412463483a..07960cbb290628 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 8a00be4b06c4ef..b3f07344a65411 100644 --- a/blocks/library/video/index.js +++ b/blocks/library/video/index.js @@ -144,7 +144,7 @@ registerBlockType( 'core/video', { return (
{ src &&
); }, From e9b711128b07daaca4698a1f85239053166d09f4 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 3 Nov 2017 13:45:07 +0100 Subject: [PATCH 11/11] 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 2bb86858682fcd..9dae20126cf4f8 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 2e1312abeebbb8..f8adbcb70b13f0 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 5d449560556c0b..f313f0bfedd9ce 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 70b5d12f587f85..263475300a8aa9 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 5df27e245b0a89..26e762cd72ecba 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 30fc79f32ec9cc..903ebe15ad388f 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 1536019ecafdc6..b5b5d65f70a63f 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 ea6086442626c6..fb2224afc571df 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 fae1598a867377..c5a03b3df6f339 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 f1ccdb20a71e79..e95a11e6e47ed1 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 8ca20af2984b81..5c5534fc02a955 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 282a309eaab7fe..c3a2834f41d989 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 761c5777e89e63..dc29e8ad9854e4 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 384bda9218663b..b28085a8a92675 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 0a2d91e079fa54..d8e8334c0fff04 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 cade58be9ae1fe..197ea44792d644 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 a9abf1806fa033..70b62db1e745ca 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 ef939548fa903a..5c8b81e0641250 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 07960cbb290628..61eb412463483a 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 b3f07344a65411..8a00be4b06c4ef 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 d73c5ce0e53232..d4cd9d97290ee0 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 f136b915cc1646..dfe2c609a3580d 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",