From 30f60630c63ccfa0541d443adc1b7cf345175000 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 5 Jan 2018 09:42:23 -0500 Subject: [PATCH] Parser: Apply autop to fallback block content --- blocks/api/parser.js | 73 +++++++++++-------- blocks/api/test/parser.js | 2 +- .../core__4-invalid-starting-letter.json | 4 +- ..._4-invalid-starting-letter.serialized.html | 2 +- blocks/test/fixtures/core__freeform.json | 4 +- .../fixtures/core__freeform.serialized.html | 4 +- .../fixtures/core__freeform__undelimited.json | 4 +- ...ore__freeform__undelimited.serialized.html | 4 +- .../test/fixtures/core__invalid-Capitals.json | 4 +- .../core__invalid-Capitals.serialized.html | 2 +- .../test/fixtures/core__invalid-special.json | 4 +- .../core__invalid-special.serialized.html | 2 +- package-lock.json | 5 ++ package.json | 1 + 14 files changed, 68 insertions(+), 47 deletions(-) diff --git a/blocks/api/parser.js b/blocks/api/parser.js index 82add30a463e8..6ee4089e00d43 100644 --- a/blocks/api/parser.js +++ b/blocks/api/parser.js @@ -4,6 +4,11 @@ import { parse as hpqParse } from 'hpq'; import { mapValues, omit } from 'lodash'; +/** + * WordPress dependencies + */ +import { autop } from '@wordpress/autop'; + /** * Internal dependencies */ @@ -175,7 +180,16 @@ export function createBlockWithFallback( name, innerHTML, attributes ) { // Try finding type for known block name, else fall back again. let blockType = getBlockType( name ); + const fallbackBlock = getUnknownTypeHandlerName(); + + // Fallback content may be upgraded from classic editor expecting implicit + // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, + // meaning there are no negative consequences to repeated autop calls. + if ( name === fallbackBlock ) { + innerHTML = autop( innerHTML ).trim(); + } + if ( ! blockType ) { // If detected as a block which is not registered, preserve comment // delimiters in content of unknown type handler. @@ -188,40 +202,41 @@ export function createBlockWithFallback( name, innerHTML, attributes ) { } // Include in set only if type were determined. - // TODO do we ever expect there to not be an unknown type handler? - if ( blockType && ( innerHTML || name !== fallbackBlock ) ) { - // TODO allow blocks to opt-in to receiving a tree instead of a string. - // Gradually convert all blocks to this new format, then remove the - // string serialization. - const block = createBlock( - name, - getBlockAttributes( blockType, innerHTML, attributes ) - ); + if ( ! blockType || ( ! innerHTML && name === fallbackBlock ) ) { + return; + } + + const block = createBlock( + name, + getBlockAttributes( blockType, innerHTML, attributes ) + ); - // Validate that the parsed block is valid, meaning that if we were to - // reserialize it given the assumed attributes, the markup matches the - // original value. + // Validate that the parsed block is valid, meaning that if we were to + // reserialize it given the assumed attributes, the markup matches the + // original value. + if ( name !== fallbackBlock ) { block.isValid = isValidBlock( innerHTML, blockType, block.attributes ); + } - // Preserve original content for future use in case the block is parsed - // as invalid, or future serialization attempt results in an error - block.originalContent = innerHTML; - - // When a block is invalid, attempt to parse it using a supplied `deprecated` definition. - // This allows blocks to modify their attribute and markup structure without invalidating - // content written in previous formats. - if ( ! block.isValid ) { - const attributesParsedWithDeprecatedVersion = getAttributesFromDeprecatedVersion( - blockType, innerHTML, attributes - ); - if ( attributesParsedWithDeprecatedVersion ) { - block.isValid = true; - block.attributes = attributesParsedWithDeprecatedVersion; - } - } + // Preserve original content for future use in case the block is parsed as + // invalid, or future serialization attempt results in an error. + block.originalContent = innerHTML; - return block; + // When block is invalid, attempt to parse it using deprecated definition. + // This enables blocks to modify attribute and markup structure without + // invalidating content written in previous formats. + if ( ! block.isValid ) { + const attributesParsedWithDeprecatedVersion = getAttributesFromDeprecatedVersion( + blockType, innerHTML, attributes + ); + + if ( attributesParsedWithDeprecatedVersion ) { + block.isValid = true; + block.attributes = attributesParsedWithDeprecatedVersion; + } } + + return block; } /** diff --git a/blocks/api/test/parser.js b/blocks/api/test/parser.js index 709ed53744aed..1d8069e1a5c71 100644 --- a/blocks/api/test/parser.js +++ b/blocks/api/test/parser.js @@ -267,7 +267,7 @@ describe( 'block parser', () => { const block = createBlockWithFallback( null, 'content' ); expect( block.name ).toEqual( 'core/unknown-block' ); - expect( block.attributes ).toEqual( { content: 'content' } ); + expect( block.attributes ).toEqual( { content: '

content

' } ); } ); it( 'should not create a block if no unknown type handler', () => { diff --git a/blocks/test/fixtures/core__4-invalid-starting-letter.json b/blocks/test/fixtures/core__4-invalid-starting-letter.json index a497b39b93f98..5515c7e9eade7 100644 --- a/blocks/test/fixtures/core__4-invalid-starting-letter.json +++ b/blocks/test/fixtures/core__4-invalid-starting-letter.json @@ -4,8 +4,8 @@ "name": "core/freeform", "isValid": true, "attributes": { - "content": "" + "content": "

" }, - "originalContent": "" + "originalContent": "

" } ] diff --git a/blocks/test/fixtures/core__4-invalid-starting-letter.serialized.html b/blocks/test/fixtures/core__4-invalid-starting-letter.serialized.html index 220f8b60c8d65..fe35001a46b8e 100644 --- a/blocks/test/fixtures/core__4-invalid-starting-letter.serialized.html +++ b/blocks/test/fixtures/core__4-invalid-starting-letter.serialized.html @@ -1 +1 @@ - +

diff --git a/blocks/test/fixtures/core__freeform.json b/blocks/test/fixtures/core__freeform.json index e475c94650121..cdeb5e8293fa2 100644 --- a/blocks/test/fixtures/core__freeform.json +++ b/blocks/test/fixtures/core__freeform.json @@ -4,8 +4,8 @@ "name": "core/freeform", "isValid": true, "attributes": { - "content": "Testing freeform block with some\n
\n\tHTML content\n
" + "content": "

Testing freeform block with some\n

\n\tHTML content\n
" }, - "originalContent": "Testing freeform block with some\n
\n\tHTML content\n
" + "originalContent": "

Testing freeform block with some\n

\n\tHTML content\n
" } ] diff --git a/blocks/test/fixtures/core__freeform.serialized.html b/blocks/test/fixtures/core__freeform.serialized.html index 2c349303c54e0..4fed04550b031 100644 --- a/blocks/test/fixtures/core__freeform.serialized.html +++ b/blocks/test/fixtures/core__freeform.serialized.html @@ -1,4 +1,4 @@ -Testing freeform block with some -
+

Testing freeform block with some +

HTML content
diff --git a/blocks/test/fixtures/core__freeform__undelimited.json b/blocks/test/fixtures/core__freeform__undelimited.json index e475c94650121..cdeb5e8293fa2 100644 --- a/blocks/test/fixtures/core__freeform__undelimited.json +++ b/blocks/test/fixtures/core__freeform__undelimited.json @@ -4,8 +4,8 @@ "name": "core/freeform", "isValid": true, "attributes": { - "content": "Testing freeform block with some\n
\n\tHTML content\n
" + "content": "

Testing freeform block with some\n

\n\tHTML content\n
" }, - "originalContent": "Testing freeform block with some\n
\n\tHTML content\n
" + "originalContent": "

Testing freeform block with some\n

\n\tHTML content\n
" } ] diff --git a/blocks/test/fixtures/core__freeform__undelimited.serialized.html b/blocks/test/fixtures/core__freeform__undelimited.serialized.html index 2c349303c54e0..4fed04550b031 100644 --- a/blocks/test/fixtures/core__freeform__undelimited.serialized.html +++ b/blocks/test/fixtures/core__freeform__undelimited.serialized.html @@ -1,4 +1,4 @@ -Testing freeform block with some -
+

Testing freeform block with some +

HTML content
diff --git a/blocks/test/fixtures/core__invalid-Capitals.json b/blocks/test/fixtures/core__invalid-Capitals.json index 7fac37fcb660d..8a320995a2224 100644 --- a/blocks/test/fixtures/core__invalid-Capitals.json +++ b/blocks/test/fixtures/core__invalid-Capitals.json @@ -4,8 +4,8 @@ "name": "core/freeform", "isValid": true, "attributes": { - "content": "" + "content": "

" }, - "originalContent": "" + "originalContent": "

" } ] diff --git a/blocks/test/fixtures/core__invalid-Capitals.serialized.html b/blocks/test/fixtures/core__invalid-Capitals.serialized.html index 1eaeb570265d9..4b0ff53da7118 100644 --- a/blocks/test/fixtures/core__invalid-Capitals.serialized.html +++ b/blocks/test/fixtures/core__invalid-Capitals.serialized.html @@ -1 +1 @@ - +

diff --git a/blocks/test/fixtures/core__invalid-special.json b/blocks/test/fixtures/core__invalid-special.json index 409611dcfe89e..08728b7a4d8e7 100644 --- a/blocks/test/fixtures/core__invalid-special.json +++ b/blocks/test/fixtures/core__invalid-special.json @@ -4,8 +4,8 @@ "name": "core/freeform", "isValid": true, "attributes": { - "content": "" + "content": "

" }, - "originalContent": "" + "originalContent": "

" } ] diff --git a/blocks/test/fixtures/core__invalid-special.serialized.html b/blocks/test/fixtures/core__invalid-special.serialized.html index 548aef63c749b..de4f2acc41f8d 100644 --- a/blocks/test/fixtures/core__invalid-special.serialized.html +++ b/blocks/test/fixtures/core__invalid-special.serialized.html @@ -1 +1 @@ - +

diff --git a/package-lock.json b/package-lock.json index cf26000712bbd..9a5f1a72a3c4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -216,6 +216,11 @@ "@wordpress/dom-ready": "0.1.0-beta.6" } }, + "@wordpress/autop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-1.0.0.tgz", + "integrity": "sha512-T9So2pdbjAY7BENLjD9XomkfeofER5DWHuvJdLisxCW4kupSXK+TKu899FLkPcrDPTAL2M520zYOzQmPobzrJg==" + }, "@wordpress/dom-ready": { "version": "0.1.0-beta.6", "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-0.1.0-beta.6.tgz", diff --git a/package.json b/package.json index 22ce1cb7f924a..32655d02117e0 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@wordpress/a11y": "0.1.0-beta.1", + "@wordpress/autop": "1.0.0", "@wordpress/hooks": "1.0.1", "@wordpress/url": "0.1.0-beta.1", "classnames": "2.2.5",