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 0ccf4cf8d8832..bc66742a85804 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 10de33f38900e..f988be555d44b 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 46fdf9c1b543d..b5b5d65f70a63 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 7404a4cb5333c..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 (
-

{ title }

+

); }, diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index 9b53cf9a11116..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 &&
{ caption }
} + { caption && caption.length > 0 &&
}
); }, diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index 9fbca6f3c4bda..9b28842842a92 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 4c94d5f26de71..5c5534fc02a95 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 b136253422fe1..c3a2834f41d98 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 983661ce52446..adc0d60a125ff 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 e5fe21e7a6d6e..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
{ content }
; + return
; }, } ); diff --git a/blocks/library/pullquote/index.js b/blocks/library/pullquote/index.js index fc55e75ecf0ed..d8e8334c0fff0 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 3b7a6a1061849..197ea44792d64 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 861017d695fcf..df657d5e676de 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 a84684c9285e6..3a9e9ad542137 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 7c553121bacb0..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
{ attributes.content }
; + return
; }, } ); diff --git a/blocks/library/video/index.js b/blocks/library/video/index.js index 427054dbbabb0..8a00be4b06c4e 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 19562063157f8..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/text-columns/index.js b/blocks/library/text-columns/index.js index 3a9e9ad542137..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 && content[ index ] && }

) }
diff --git a/docs/blocks-controls.md b/docs/blocks-controls.md index 50d96ce1e3029..7fb73df073246 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 7a5a9ce3fa77e..a819233bd4260 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 f988be555d44b..2e7c26ed2e62e 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 8213fbf8e700c..8d14fcaf65dea 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 39674931b4429..2f6af6a1afcf5 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 15bc029cf8de1..9e03274c49e4a 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 37ca66e8c95ad..a3bbb9daac74e 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 5ebe0b5564fb2..f0235d70916cf 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 29eed74d38b3b..520b982dd6c0b 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 bea152f89f32c..7f048eb1c35fc 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 ea48f03aef42f..e5daf2ff8b519 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 2ecdee94dd749..dfb3610bb2c99 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 0efed063a93be..684fd2f9db6b3 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 0baa254be043a..4633bbe53681b 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 32d1246a2e9d6..52d2986f9b034 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 2e7c26ed2e62e..06856f9eb798a 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 8d14fcaf65dea..711869f552e4e 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 bc66742a85804..bcbcfa2cffd2c 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 52d2986f9b034..0c6d3250026b8 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 711869f552e4e..70b5d12f587f8 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 df657d5e676de..70b62db1e745c 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 520b982dd6c0b..6e0e4e3d45e45 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 0c6d3250026b8..2e1312abeebbb 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 7fb73df073246..fb1196e17f8a3 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 a819233bd4260..334dedda56b56 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 bcbcfa2cffd2c..bc9239f495b38 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 0000000000000..9dae20126cf4f --- /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 06856f9eb798a..363edbbc1ef0c 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 9b28842842a92..e95a11e6e47ed 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 adc0d60a125ff..dc29e8ad9854e 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 9dae20126cf4f..2bb86858682fc 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 363edbbc1ef0c..5d449560556c0 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 26e762cd72ecb..5df27e245b0a8 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 903ebe15ad388..30fc79f32ec9c 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 b5b5d65f70a63..1536019ecafdc 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 fb2224afc571d..ea6086442626c 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 c5a03b3df6f33..fae1598a86737 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 e95a11e6e47ed..f1ccdb20a71e7 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 5c5534fc02a95..8ca20af2984b8 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 c3a2834f41d98..282a309eaab7f 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 dc29e8ad9854e..761c5777e89e6 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 b28085a8a9267..384bda9218663 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 d8e8334c0fff0..0a2d91e079fa5 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 197ea44792d64..cade58be9ae1f 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 70b62db1e745c..a9abf1806fa03 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 5c8b81e064125..ef939548fa903 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 61eb412463483..07960cbb29062 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 8a00be4b06c4e..b3f07344a6541 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 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",