From 18e5a72a2fabca4bff154aa57a7ea84e611ed8f4 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 12 Apr 2017 11:50:50 +0100 Subject: [PATCH 01/11] Editable: Enter splits the current paragraph into two blocks --- blocks/components/editable/index.js | 28 ++++++++++++++++++++++++++++ blocks/library/text/index.js | 18 ++++++++++++++++-- editor/modes/visual-editor/block.js | 13 +++++++++++-- editor/state.js | 14 ++++++++------ editor/test/state.js | 27 +++++++++++++++++++++++++++ languages/gutenberg.pot | 8 ++++---- 6 files changed, 94 insertions(+), 14 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index ff37f8692f98a5..24a446b6d4ecd8 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -14,6 +14,7 @@ export default class Editable extends wp.element.Component { this.onInit = this.onInit.bind( this ); this.onSetup = this.onSetup.bind( this ); this.onChange = this.onChange.bind( this ); + this.onKeyDown = this.onKeyDown.bind( this ); this.bindNode = this.bindNode.bind( this ); } @@ -42,6 +43,7 @@ export default class Editable extends wp.element.Component { this.editor = editor; editor.on( 'init', this.onInit ); editor.on( 'focusout', this.onChange ); + editor.on( 'keydown', this.onKeyDown ); } onInit() { @@ -58,6 +60,28 @@ export default class Editable extends wp.element.Component { this.props.onChange( value ); } + onKeyDown( event ) { + if ( ! this.props.tagName && event.keyCode === 13 ) { + // Wait for the event to propagate + setTimeout( () => { + // Getting the content before and after the cursor + this.editor.selection.getStart(); + const childNodes = Array.from( this.editor.getBody().childNodes ); + const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); + const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); + const beforeNodes = childNodes.slice( 0, splitIndex ); + const before = getHtml( beforeNodes ); + const after = getHtml( childNodes.slice( splitIndex ) ); + + // Splitting into two blocks + this.editor.setContent( this.props.value ); + const hasAfter = !! childNodes.slice( splitIndex ) + .reduce( ( memo, node ) => memo + node.textContent, '' ); + this.props.onSplit( before, hasAfter ? after : '' ); + } ); + } + } + bindNode( ref ) { this.node = ref; } @@ -100,3 +124,7 @@ export default class Editable extends wp.element.Component { ); } } + +Editable.defaultProps = { + onSplit: () => {} +}; diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index 3d3033d2181933..b2c31e28af0753 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import uuid from 'uuid/v4'; + /** * Internal dependencies */ @@ -45,15 +50,24 @@ registerBlock( 'core/text', { } ], - edit( { attributes, setAttributes } ) { + edit( { attributes, setAttributes, insertBlockAfter } ) { const { content, align } = attributes; return ( setAttributes( { content: value } ) } style={ align ? { textAlign: align } : null } + onSplit={ ( before, after ) => { + setAttributes( { content: before } ); + insertBlockAfter( { + uid: uuid(), + blockType: 'core/text', + attributes: { + content: after + } + } ); + } } /> ); }, diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index 49eef6a1d2dd3c..bf8b1bf8e105e4 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -30,7 +30,7 @@ function VisualEditorBlock( props ) { 'is-hovered': isHovered } ); - const { onChange, onSelect, onDeselect, onMouseEnter, onMouseLeave } = props; + const { onChange, onSelect, onDeselect, onMouseEnter, onMouseLeave, onInsertAfter } = props; function setAttributes( attributes ) { onChange( { @@ -75,7 +75,9 @@ function VisualEditorBlock( props ) { + setAttributes={ setAttributes } + insertBlockAfter={ onInsertAfter } + /> ); /* eslint-enable jsx-a11y/no-static-element-interactions */ @@ -122,6 +124,13 @@ export default connect( hovered: false, uid: ownProps.uid } ); + }, + onInsertAfter( block ) { + dispatch( { + type: 'INSERT_BLOCK', + after: ownProps.uid, + block + } ); } } ) )( VisualEditorBlock ); diff --git a/editor/state.js b/editor/state.js index 11dcf707a7128f..d5825bf2aa1bab 100644 --- a/editor/state.js +++ b/editor/state.js @@ -48,6 +48,14 @@ export const blocks = combineUndoableReducers( { case 'REPLACE_BLOCKS': return action.blockNodes.map( ( { uid } ) => uid ); + case 'INSERT_BLOCK': + const position = action.after ? state.indexOf( action.after ) + 1 : state.length; + return [ + ...state.slice( 0, position ), + action.block.uid, + ...state.slice( position ) + ]; + case 'MOVE_BLOCK_UP': if ( action.uid === state[ 0 ] ) { return state; @@ -73,12 +81,6 @@ export const blocks = combineUndoableReducers( { action.uid, ...state.slice( index + 2 ) ]; - - case 'INSERT_BLOCK': - return [ - ...state, - action.block.uid - ]; } return state; diff --git a/editor/test/state.js b/editor/test/state.js index 0174602989ae8e..44eb1218d67cb3 100644 --- a/editor/test/state.js +++ b/editor/test/state.js @@ -235,6 +235,33 @@ describe( 'state', () => { expect( state ).to.equal( 'chicken' ); } ); + + it( 'should insert after the specified block uid', () => { + const original = blocks( undefined, { + type: 'REPLACE_BLOCKS', + blockNodes: [ { + uid: 'kumquat', + blockType: 'core/test-block', + attributes: {} + }, { + uid: 'kumquat2', + blockType: 'core/test-block', + attributes: {} + } ] + } ); + + const state = blocks( original, { + type: 'INSERT_BLOCK', + after: 'kumquat', + block: { + uid: 'kumquat3', + blockType: 'core/freeform' + } + } ); + + expect( Object.keys( state.byUid ) ).to.have.lengthOf( 3 ); + expect( state.order ).to.eql( [ 'kumquat', 'kumquat3', 'kumquat2' ] ); + } ); } ); describe( 'mode()', () => { diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot index 0139235b67a693..2e6c4cb3e0ac89 100644 --- a/languages/gutenberg.pot +++ b/languages/gutenberg.pot @@ -28,17 +28,17 @@ msgid "List" msgstr "" #: blocks/library/list/index.js:25 -#: blocks/library/text/index.js:24 +#: blocks/library/text/index.js:29 msgid "Align left" msgstr "" #: blocks/library/list/index.js:33 -#: blocks/library/text/index.js:32 +#: blocks/library/text/index.js:37 msgid "Align center" msgstr "" #: blocks/library/list/index.js:41 -#: blocks/library/text/index.js:40 +#: blocks/library/text/index.js:45 msgid "Align right" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "Quote" msgstr "" -#: blocks/library/text/index.js:10 +#: blocks/library/text/index.js:15 msgid "Text" msgstr "" From 07e6edf16e9e948af3244dab9abb2c8803cc0c6e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 13 Apr 2017 10:33:35 +0100 Subject: [PATCH 02/11] Split text block on double enter --- blocks/components/editable/index.js | 48 ++++++++++++++++++----------- blocks/library/text/index.js | 9 +++--- post-content.js | 6 ++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 24a446b6d4ecd8..e8a3e0c1685e2b 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -2,6 +2,7 @@ * External dependencies */ import classnames from 'classnames'; +import { last } from 'lodash'; /** * Internal dependencies @@ -61,25 +62,36 @@ export default class Editable extends wp.element.Component { } onKeyDown( event ) { - if ( ! this.props.tagName && event.keyCode === 13 ) { - // Wait for the event to propagate - setTimeout( () => { - // Getting the content before and after the cursor - this.editor.selection.getStart(); - const childNodes = Array.from( this.editor.getBody().childNodes ); - const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); - const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); - const beforeNodes = childNodes.slice( 0, splitIndex ); - const before = getHtml( beforeNodes ); - const after = getHtml( childNodes.slice( splitIndex ) ); - - // Splitting into two blocks - this.editor.setContent( this.props.value ); - const hasAfter = !! childNodes.slice( splitIndex ) - .reduce( ( memo, node ) => memo + node.textContent, '' ); - this.props.onSplit( before, hasAfter ? after : '' ); - } ); + if ( this.props.tagName || event.keyCode !== 13 ) { + return; } + + // Wait for the event to propagate + setTimeout( () => { + // Getting the content before and after the cursor + this.editor.selection.getStart(); + const childNodes = Array.from( this.editor.getBody().childNodes ); + const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); + const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); + const beforeNodes = childNodes.slice( 0, splitIndex ); + const lastNodeBeforeCursor = last( beforeNodes ); + // Avoid splitting on single enter + if ( + ! lastNodeBeforeCursor || + lastNodeBeforeCursor.childNodes.length !== 1 || + lastNodeBeforeCursor.firstChild.tagName !== 'BR' + ) { + return; + } + const before = getHtml( beforeNodes.slice( 0, beforeNodes.length - 1 ) ); + const after = getHtml( childNodes.slice( splitIndex ) ); + + // Splitting into two blocks + this.editor.setContent( this.props.value ); + const hasAfter = !! childNodes.slice( splitIndex ) + .reduce( ( memo, node ) => memo + node.textContent, '' ); + this.props.onSplit( before, hasAfter ? after : '' ); + } ); } bindNode( ref ) { diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index b2c31e28af0753..6e36541d186c7f 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -19,8 +19,8 @@ registerBlock( 'core/text', { category: 'common', attributes: { - content: html( 'p' ), - align: prop( 'p', 'style.textAlign' ) + content: html( 'div' ), + align: prop( 'div', 'style.textAlign' ) }, controls: [ @@ -76,9 +76,10 @@ registerBlock( 'core/text', { const { align, content } = attributes; return ( -

+ dangerouslySetInnerHTML={ { __html: content } } + /> ); } } ); diff --git a/post-content.js b/post-content.js index 844d28282abd2d..152d43f9ec3507 100644 --- a/post-content.js +++ b/post-content.js @@ -9,7 +9,7 @@ window._wpGutenbergPost = { '', '', - '

I imagine prior to the launch of the iPod, or the iPhone, there were teams saying the same thing: the copy + paste guys are so close to being ready and we know Walt Mossberg is going to ding us for this so let\'s just not ship to the manufacturers in China for just a few more weeks… The Apple teams were probably embarrassed. But if you\'re not embarrassed when you ship your first version you waited too long.

', + '

I imagine prior to the launch of the iPod, or the iPhone, there were teams saying the same thing: the copy + paste guys are so close to being ready and we know Walt Mossberg is going to ding us for this so let\'s just not ship to the manufacturers in China for just a few more weeks… The Apple teams were probably embarrassed. But if you\'re not embarrassed when you ship your first version you waited too long.

', '', '', @@ -17,7 +17,7 @@ window._wpGutenbergPost = { '', '', - '

A beautiful thing about Apple is how quickly they obsolete their own products. I imagine this also makes the discipline of getting things out there easier. Like I mentioned before, the longer it’s been since the last release the more pressure there is, but if you know that if your bit of code doesn’t make this version but there’s the +0.1 coming out in 6 weeks, then it’s not that bad. It’s like flights from San Francisco to LA, if you miss one you know there’s another one an hour later so it’s not a big deal. Amazon has done a fantastic job of this with the Kindle as well, with a new model every year.

', + '

A beautiful thing about Apple is how quickly they obsolete their own products. I imagine this also makes the discipline of getting things out there easier. Like I mentioned before, the longer it’s been since the last release the more pressure there is, but if you know that if your bit of code doesn’t make this version but there’s the +0.1 coming out in 6 weeks, then it’s not that bad. It’s like flights from San Francisco to LA, if you miss one you know there’s another one an hour later so it’s not a big deal. Amazon has done a fantastic job of this with the Kindle as well, with a new model every year.

', '', '', @@ -29,7 +29,7 @@ window._wpGutenbergPost = { '', '', - '

By shipping early and often you have the unique competitive advantage of hearing from real people what they think of your work, which in best case helps you anticipate market direction, and in worst case gives you a few people rooting for you that you can email when your team pivots to a new idea. Nothing can recreate the crucible of real usage.

', + '

By shipping early and often you have the unique competitive advantage of hearing from real people what they think of your work, which in best case helps you anticipate market direction, and in worst case gives you a few people rooting for you that you can email when your team pivots to a new idea. Nothing can recreate the crucible of real usage.

', '', '', From 50f49b448e56de862eab0235860f0e93873dc2a9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 09:28:52 +0100 Subject: [PATCH 03/11] Avoid defaultProps --- blocks/components/editable/index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index e8a3e0c1685e2b..3fa4cbd8cfe718 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -62,7 +62,7 @@ export default class Editable extends wp.element.Component { } onKeyDown( event ) { - if ( this.props.tagName || event.keyCode !== 13 ) { + if ( this.props.tagName || event.keyCode !== 13 || ! this.props.onSplit ) { return; } @@ -136,7 +136,3 @@ export default class Editable extends wp.element.Component { ); } } - -Editable.defaultProps = { - onSplit: () => {} -}; From 9a23d2030d46b3e32101c151dd9449e1b22f13ac Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 09:32:44 +0100 Subject: [PATCH 04/11] Original test strings --- editor/test/state.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/editor/test/state.js b/editor/test/state.js index 44eb1218d67cb3..6c3983f2f6f476 100644 --- a/editor/test/state.js +++ b/editor/test/state.js @@ -244,7 +244,7 @@ describe( 'state', () => { blockType: 'core/test-block', attributes: {} }, { - uid: 'kumquat2', + uid: 'loquat', blockType: 'core/test-block', attributes: {} } ] @@ -254,13 +254,13 @@ describe( 'state', () => { type: 'INSERT_BLOCK', after: 'kumquat', block: { - uid: 'kumquat3', + uid: 'persimmon', blockType: 'core/freeform' } } ); expect( Object.keys( state.byUid ) ).to.have.lengthOf( 3 ); - expect( state.order ).to.eql( [ 'kumquat', 'kumquat3', 'kumquat2' ] ); + expect( state.order ).to.eql( [ 'kumquat', 'persimmon', 'loquat' ] ); } ); } ); From 0dc010bad71399c3b2beec7f670fed8a4ea48026 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 09:34:19 +0100 Subject: [PATCH 05/11] Using the create block helper --- blocks/library/text/index.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index 6e36541d186c7f..5c86885e8cdb4a 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -60,13 +60,9 @@ registerBlock( 'core/text', { style={ align ? { textAlign: align } : null } onSplit={ ( before, after ) => { setAttributes( { content: before } ); - insertBlockAfter( { - uid: uuid(), - blockType: 'core/text', - attributes: { - content: after - } - } ); + insertBlockAfter( wp.blocks.createBlock( 'core/text', { + content: after + } ) ); } } /> ); From 706fbc5a1299a0a5cd86f0c865eb02dd8a5055c4 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 09:42:25 +0100 Subject: [PATCH 06/11] Fix the paragraph styling --- blocks/components/editable/style.scss | 14 ++++++++++++-- editor/modes/visual-editor/style.scss | 5 ----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/blocks/components/editable/style.scss b/blocks/components/editable/style.scss index 1a143b68d8ea17..468315ca41743b 100644 --- a/blocks/components/editable/style.scss +++ b/blocks/components/editable/style.scss @@ -1,3 +1,13 @@ -.blocks-editable:focus { - outline: none; +.blocks-editable { + > p:first-child { + margin-top: 0; + } + + > p:last-child { + margin-bottom: 0; + } + + &:focus { + outline: none; + } } diff --git a/editor/modes/visual-editor/style.scss b/editor/modes/visual-editor/style.scss index 60c27fb03eac4e..04ef444ebc526b 100644 --- a/editor/modes/visual-editor/style.scss +++ b/editor/modes/visual-editor/style.scss @@ -8,11 +8,6 @@ font-size: $editor-font-size; line-height: $editor-line-height; } - - p { - margin-top: 0; - margin-bottom: 0; - } } .editor-visual-editor__block { From 75a0f0d7de386fc883218a3e34cc93808bb70d83 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 09:47:07 +0100 Subject: [PATCH 07/11] Dropping unused dependency uuid --- blocks/library/text/index.js | 5 ----- languages/gutenberg.pot | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index 5c86885e8cdb4a..7250c2e047ea8d 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import uuid from 'uuid/v4'; - /** * Internal dependencies */ diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot index 2e6c4cb3e0ac89..0139235b67a693 100644 --- a/languages/gutenberg.pot +++ b/languages/gutenberg.pot @@ -28,17 +28,17 @@ msgid "List" msgstr "" #: blocks/library/list/index.js:25 -#: blocks/library/text/index.js:29 +#: blocks/library/text/index.js:24 msgid "Align left" msgstr "" #: blocks/library/list/index.js:33 -#: blocks/library/text/index.js:37 +#: blocks/library/text/index.js:32 msgid "Align center" msgstr "" #: blocks/library/list/index.js:41 -#: blocks/library/text/index.js:45 +#: blocks/library/text/index.js:40 msgid "Align right" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "Quote" msgstr "" -#: blocks/library/text/index.js:15 +#: blocks/library/text/index.js:10 msgid "Text" msgstr "" From 49a169e020857da751dddf3db68a13ca5b949c9e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 17 Apr 2017 14:13:40 +0100 Subject: [PATCH 08/11] Fix splitting behaviour when we have some formatting --- blocks/components/editable/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 3fa4cbd8cfe718..139d7a481ccbc8 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -78,8 +78,7 @@ export default class Editable extends wp.element.Component { // Avoid splitting on single enter if ( ! lastNodeBeforeCursor || - lastNodeBeforeCursor.childNodes.length !== 1 || - lastNodeBeforeCursor.firstChild.tagName !== 'BR' + !! lastNodeBeforeCursor.textContent ) { return; } From de3265ac1f27ee9bd9ab39fbd741d04a8ea4eeb4 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 18 Apr 2017 09:39:43 +0100 Subject: [PATCH 09/11] - No div wrapper for text block - Do not split when hitting Enter on the first row - Fix the nullable value error --- blocks/components/editable/index.js | 7 ++++-- blocks/library/text/index.js | 34 +++++++++++++++++++---------- languages/gutenberg.pot | 8 +++---- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 139d7a481ccbc8..60acb76bc92dcc 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -68,8 +68,10 @@ export default class Editable extends wp.element.Component { // Wait for the event to propagate setTimeout( () => { + if ( ! this.editor ) { + return; + } // Getting the content before and after the cursor - this.editor.selection.getStart(); const childNodes = Array.from( this.editor.getBody().childNodes ); const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); @@ -78,6 +80,7 @@ export default class Editable extends wp.element.Component { // Avoid splitting on single enter if ( ! lastNodeBeforeCursor || + beforeNodes.length < 2 || !! lastNodeBeforeCursor.textContent ) { return; @@ -86,7 +89,7 @@ export default class Editable extends wp.element.Component { const after = getHtml( childNodes.slice( splitIndex ) ); // Splitting into two blocks - this.editor.setContent( this.props.value ); + this.editor.setContent( this.props.value || '' ); const hasAfter = !! childNodes.slice( splitIndex ) .reduce( ( memo, node ) => memo + node.textContent, '' ); this.props.onSplit( before, hasAfter ? after : '' ); diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index 7250c2e047ea8d..f793cddca9e768 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -1,10 +1,13 @@ /** * Internal dependencies */ -import { registerBlock, query } from 'api'; +import { registerBlock, query as hpq } from 'api'; import Editable from 'components/editable'; -const { html, prop } = query; +const { html, parse, query } = hpq; + +const fromValueToParagraphs = ( value ) => value ? value.map( ( paragraph ) => `

${ paragraph }

` ).join( '' ) : ''; +const fromParagraphsToValue = ( paragraphs ) => parse( paragraphs, query( 'p', html() ) ); registerBlock( 'core/text', { title: wp.i18n.__( 'Text' ), @@ -14,8 +17,7 @@ registerBlock( 'core/text', { category: 'common', attributes: { - content: html( 'div' ), - align: prop( 'div', 'style.textAlign' ) + content: query( 'p', html() ), }, controls: [ @@ -50,13 +52,15 @@ registerBlock( 'core/text', { return ( setAttributes( { content: value } ) } + value={ fromValueToParagraphs( content ) } + onChange={ ( paragraphs ) => setAttributes( { + content: fromParagraphsToValue( paragraphs ) + } ) } style={ align ? { textAlign: align } : null } onSplit={ ( before, after ) => { - setAttributes( { content: before } ); + setAttributes( { content: fromParagraphsToValue( before ) } ); insertBlockAfter( wp.blocks.createBlock( 'core/text', { - content: after + content: fromParagraphsToValue( after ) } ) ); } } /> @@ -67,10 +71,16 @@ registerBlock( 'core/text', { const { align, content } = attributes; return ( -
+
+ { content && content.map( ( paragraph, i ) => ( +

+ ) ) } +

); } } ); diff --git a/languages/gutenberg.pot b/languages/gutenberg.pot index 0139235b67a693..940666763cb115 100644 --- a/languages/gutenberg.pot +++ b/languages/gutenberg.pot @@ -28,17 +28,17 @@ msgid "List" msgstr "" #: blocks/library/list/index.js:25 -#: blocks/library/text/index.js:24 +#: blocks/library/text/index.js:26 msgid "Align left" msgstr "" #: blocks/library/list/index.js:33 -#: blocks/library/text/index.js:32 +#: blocks/library/text/index.js:34 msgid "Align center" msgstr "" #: blocks/library/list/index.js:41 -#: blocks/library/text/index.js:40 +#: blocks/library/text/index.js:42 msgid "Align right" msgstr "" @@ -50,7 +50,7 @@ msgstr "" msgid "Quote" msgstr "" -#: blocks/library/text/index.js:10 +#: blocks/library/text/index.js:13 msgid "Text" msgstr "" From fbdec2b4604351f3ece3a7dbcf4263671fb56db5 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 18 Apr 2017 09:54:09 +0100 Subject: [PATCH 10/11] Using newBlock event instead of using setTimeout --- blocks/components/editable/index.js | 58 +++++++++++++---------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 60acb76bc92dcc..0e2e15a85cb321 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -15,7 +15,7 @@ export default class Editable extends wp.element.Component { this.onInit = this.onInit.bind( this ); this.onSetup = this.onSetup.bind( this ); this.onChange = this.onChange.bind( this ); - this.onKeyDown = this.onKeyDown.bind( this ); + this.onNewBlock = this.onNewBlock.bind( this ); this.bindNode = this.bindNode.bind( this ); } @@ -44,7 +44,7 @@ export default class Editable extends wp.element.Component { this.editor = editor; editor.on( 'init', this.onInit ); editor.on( 'focusout', this.onChange ); - editor.on( 'keydown', this.onKeyDown ); + editor.on( 'NewBlock', this.onNewBlock ); } onInit() { @@ -61,39 +61,33 @@ export default class Editable extends wp.element.Component { this.props.onChange( value ); } - onKeyDown( event ) { - if ( this.props.tagName || event.keyCode !== 13 || ! this.props.onSplit ) { + onNewBlock() { + if ( this.props.tagName || ! this.props.onSplit ) { return; } - // Wait for the event to propagate - setTimeout( () => { - if ( ! this.editor ) { - return; - } - // Getting the content before and after the cursor - const childNodes = Array.from( this.editor.getBody().childNodes ); - const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); - const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); - const beforeNodes = childNodes.slice( 0, splitIndex ); - const lastNodeBeforeCursor = last( beforeNodes ); - // Avoid splitting on single enter - if ( - ! lastNodeBeforeCursor || - beforeNodes.length < 2 || - !! lastNodeBeforeCursor.textContent - ) { - return; - } - const before = getHtml( beforeNodes.slice( 0, beforeNodes.length - 1 ) ); - const after = getHtml( childNodes.slice( splitIndex ) ); - - // Splitting into two blocks - this.editor.setContent( this.props.value || '' ); - const hasAfter = !! childNodes.slice( splitIndex ) - .reduce( ( memo, node ) => memo + node.textContent, '' ); - this.props.onSplit( before, hasAfter ? after : '' ); - } ); + // Getting the content before and after the cursor + const childNodes = Array.from( this.editor.getBody().childNodes ); + const splitIndex = childNodes.indexOf( this.editor.selection.getStart() ); + const getHtml = ( nodes ) => nodes.reduce( ( memo, node ) => memo + node.outerHTML, '' ); + const beforeNodes = childNodes.slice( 0, splitIndex ); + const lastNodeBeforeCursor = last( beforeNodes ); + // Avoid splitting on single enter + if ( + ! lastNodeBeforeCursor || + beforeNodes.length < 2 || + !! lastNodeBeforeCursor.textContent + ) { + return; + } + const before = getHtml( beforeNodes.slice( 0, beforeNodes.length - 1 ) ); + const after = getHtml( childNodes.slice( splitIndex ) ); + + // Splitting into two blocks + this.editor.setContent( this.props.value || '' ); + const hasAfter = !! childNodes.slice( splitIndex ) + .reduce( ( memo, node ) => memo + node.textContent, '' ); + this.props.onSplit( before, hasAfter ? after : '' ); } bindNode( ref ) { From ee12b370db15507a36da0fbc03afaeb0893beb26 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 18 Apr 2017 15:40:37 +0100 Subject: [PATCH 11/11] Adding a comment about the temporary wrapper --- blocks/library/text/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index f793cddca9e768..540c8c01d232a9 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -70,6 +70,7 @@ registerBlock( 'core/text', { save( { attributes } ) { const { align, content } = attributes; + // Todo: Remove the temporary
wrapper once the serializer supports returning an array return (
{ content && content.map( ( paragraph, i ) => (