From e63f62939c51db2c9c483e72b7d38c89f12464ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20Van=C2=A0Durpe?= Date: Fri, 1 Feb 2019 09:58:15 +0100 Subject: [PATCH] Fix Google Docs table paste (#13543) --- .../raw-handling/phrasing-content-reducer.js | 21 ++----------------- .../test/phrasing-content-reducer.js | 4 ---- .../blocks/src/api/raw-handling/test/utils.js | 6 ++++++ packages/blocks/src/api/raw-handling/utils.js | 16 ++++++++++++-- test/integration/blocks-raw-handling.spec.js | 1 + .../fixtures/google-docs-table-in.html | 1 + .../fixtures/google-docs-table-out.html | 3 +++ 7 files changed, 27 insertions(+), 25 deletions(-) create mode 100644 test/integration/fixtures/google-docs-table-in.html create mode 100644 test/integration/fixtures/google-docs-table-out.html diff --git a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js index 3bc6fa11fb2396..5237c28495ee79 100644 --- a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js @@ -1,18 +1,9 @@ /** * WordPress dependencies */ -import { wrap, unwrap, replaceTag } from '@wordpress/dom'; +import { wrap, replaceTag } from '@wordpress/dom'; -/** - * Internal dependencies - */ -import { isPhrasingContent } from './phrasing-content'; - -function isBlockContent( node, schema = {} ) { - return schema.hasOwnProperty( node.nodeName.toLowerCase() ); -} - -export default function( node, doc, schema ) { +export default function( node, doc ) { if ( node.nodeName === 'SPAN' ) { const { fontWeight, @@ -50,12 +41,4 @@ export default function( node, doc, schema ) { node.removeAttribute( 'rel' ); } } - - if ( - isPhrasingContent( node ) && - node.hasChildNodes() && - Array.from( node.childNodes ).some( ( child ) => isBlockContent( child, schema ) ) - ) { - unwrap( node ); - } } diff --git a/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js index 254344e50b11d3..14a9d26984956b 100644 --- a/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/test/phrasing-content-reducer.js @@ -21,10 +21,6 @@ describe( 'phrasingContentReducer', () => { expect( deepFilterHTML( 'test', [ phrasingContentReducer ], {} ) ).toEqual( 'test' ); } ); - it( 'should remove invalid phrasing content', () => { - expect( deepFilterHTML( '

test

', [ phrasingContentReducer ], { p: {} } ) ).toEqual( '

test

' ); - } ); - it( 'should normalise the rel attribute', () => { const input = 'WordPress'; const output = 'WordPress'; diff --git a/packages/blocks/src/api/raw-handling/test/utils.js b/packages/blocks/src/api/raw-handling/test/utils.js index 66b0e8ffd0a5e0..efaea872497ae9 100644 --- a/packages/blocks/src/api/raw-handling/test/utils.js +++ b/packages/blocks/src/api/raw-handling/test/utils.js @@ -186,6 +186,12 @@ describe( 'removeInvalidHTML', () => { const output = '

test

test'; expect( removeInvalidHTML( input, schema ) ).toBe( output ); } ); + + it( 'should remove invalid phrasing content', () => { + const input = '

test

'; + const output = '

test

'; + expect( removeInvalidHTML( input, schema ) ).toEqual( output ); + } ); } ); describe( 'getBlockContentSchema', () => { diff --git a/packages/blocks/src/api/raw-handling/utils.js b/packages/blocks/src/api/raw-handling/utils.js index 82f0903824a762..d917b681f94568 100644 --- a/packages/blocks/src/api/raw-handling/utils.js +++ b/packages/blocks/src/api/raw-handling/utils.js @@ -239,9 +239,21 @@ function cleanNodeList( nodeList, doc, schema, inline ) { if ( require.length && ! node.querySelector( require.join( ',' ) ) ) { cleanNodeList( node.childNodes, doc, schema, inline ); unwrap( node ); - } + // If the node is at the top, phrasing content, and + // contains children that are block content, unwrap + // the node because it is invalid. + } else if ( + node.parentNode.nodeName === 'BODY' && + isPhrasingContent( node ) + ) { + cleanNodeList( node.childNodes, doc, schema, inline ); - cleanNodeList( node.childNodes, doc, children, inline ); + if ( Array.from( node.childNodes ).some( ( child ) => ! isPhrasingContent( child ) ) ) { + unwrap( node ); + } + } else { + cleanNodeList( node.childNodes, doc, children, inline ); + } // Remove children if the node is not supposed to have any. } else { while ( node.firstChild ) { diff --git a/test/integration/blocks-raw-handling.spec.js b/test/integration/blocks-raw-handling.spec.js index 364658b1ebf9fa..4e0b6c4d60b706 100644 --- a/test/integration/blocks-raw-handling.spec.js +++ b/test/integration/blocks-raw-handling.spec.js @@ -207,6 +207,7 @@ describe( 'Blocks raw handling', () => { 'classic', 'apple', 'google-docs', + 'google-docs-table', 'ms-word', 'ms-word-styled', 'ms-word-online', diff --git a/test/integration/fixtures/google-docs-table-in.html b/test/integration/fixtures/google-docs-table-in.html new file mode 100644 index 00000000000000..8a6b117fa6ed55 --- /dev/null +++ b/test/integration/fixtures/google-docs-table-in.html @@ -0,0 +1 @@ +

One

Two

Three

1

2

3

I

II

III

diff --git a/test/integration/fixtures/google-docs-table-out.html b/test/integration/fixtures/google-docs-table-out.html new file mode 100644 index 00000000000000..697c2d41ea5cd9 --- /dev/null +++ b/test/integration/fixtures/google-docs-table-out.html @@ -0,0 +1,3 @@ + +
OneTwoThree
123
IIIIII
+