From 5ae642a2091230f9767b8010634320393a895608 Mon Sep 17 00:00:00 2001 From: Matthew Kevins Date: Tue, 19 Feb 2019 20:28:02 +1000 Subject: [PATCH] Implement pasting external content with plain and styled text (#13841) * Refactor raw-handler and paste-handler into their own files * Add undefined and null checks for jsdom-jscore node methods/properties * Implement createRecord method for converting native content to RichText * Refactor splitContent and onEnter for common interface with onPaste * Begin implementing onPaste for plain and styled text * Fix some lint errors and some invalid references. * Add undefined check for jsdom-jscore node in phrasing-content-reducer * Add onReplace method to ParagraphEdit * Refactor raw-handler back into index.js * Remove unused parameters from RichText create method --- .../src/paragraph/edit.native.js | 16 ++ packages/blocks/src/api/index.native.js | 3 +- packages/blocks/src/api/raw-handling/index.js | 167 +----------- .../src/api/raw-handling/index.native.js | 1 + .../src/api/raw-handling/paste-handler.js | 240 ++++++++++++++++++ .../raw-handling/phrasing-content-reducer.js | 8 +- packages/blocks/src/api/raw-handling/utils.js | 4 +- packages/dom/package.json | 1 + .../src/components/rich-text/index.native.js | 152 +++++++++-- packages/shortcode/package.json | 1 + 10 files changed, 407 insertions(+), 186 deletions(-) create mode 100644 packages/blocks/src/api/raw-handling/paste-handler.js diff --git a/packages/block-library/src/paragraph/edit.native.js b/packages/block-library/src/paragraph/edit.native.js index b8205240d48d1..c859f5c5216c8 100644 --- a/packages/block-library/src/paragraph/edit.native.js +++ b/packages/block-library/src/paragraph/edit.native.js @@ -22,6 +22,7 @@ class ParagraphEdit extends Component { constructor( props ) { super( props ); this.splitBlock = this.splitBlock.bind( this ); + this.onReplace = this.onReplace.bind( this ); this.state = { aztecHeight: 0, @@ -71,6 +72,20 @@ class ParagraphEdit extends Component { } } + onReplace( blocks ) { + const { attributes, onReplace } = this.props; + onReplace( blocks.map( ( block, index ) => ( + index === 0 && block.name === name ? + { ...block, + attributes: { + ...attributes, + ...block.attributes, + }, + } : + block + ) ) ); + } + render() { const { attributes, @@ -106,6 +121,7 @@ class ParagraphEdit extends Component { } } onSplit={ this.splitBlock } onMerge={ mergeBlocks } + onReplace={ this.onReplace } onContentSizeChange={ ( event ) => { this.setState( { aztecHeight: event.aztecHeight } ); } } diff --git a/packages/blocks/src/api/index.native.js b/packages/blocks/src/api/index.native.js index 7b0bd10eadfd7..2f850d36108cb 100644 --- a/packages/blocks/src/api/index.native.js +++ b/packages/blocks/src/api/index.native.js @@ -4,6 +4,7 @@ export { } from './factory'; export { default as parse, + getBlockAttributes, parseWithAttributeSchema, } from './parser'; export { @@ -28,5 +29,5 @@ export { export { isUnmodifiedDefaultBlock, } from './utils'; -export { getPhrasingContentSchema } from './raw-handling'; +export { pasteHandler, getPhrasingContentSchema } from './raw-handling'; export { default as children } from './children'; diff --git a/packages/blocks/src/api/raw-handling/index.js b/packages/blocks/src/api/raw-handling/index.js index 2de9bff8e2059..58044375d9dc3 100644 --- a/packages/blocks/src/api/raw-handling/index.js +++ b/packages/blocks/src/api/raw-handling/index.js @@ -7,52 +7,20 @@ import { flatMap, filter, compact } from 'lodash'; * Internal dependencies */ import { createBlock, getBlockTransforms, findTransform } from '../factory'; -import { getBlockContent } from '../serializer'; import { getBlockAttributes, parseWithGrammar } from '../parser'; import normaliseBlocks from './normalise-blocks'; import specialCommentConverter from './special-comment-converter'; -import isInlineContent from './is-inline-content'; -import phrasingContentReducer from './phrasing-content-reducer'; -import headRemover from './head-remover'; -import msListConverter from './ms-list-converter'; import listReducer from './list-reducer'; -import imageCorrector from './image-corrector'; import blockquoteNormaliser from './blockquote-normaliser'; import figureContentReducer from './figure-content-reducer'; import shortcodeConverter from './shortcode-converter'; -import markdownConverter from './markdown-converter'; -import iframeRemover from './iframe-remover'; -import { getPhrasingContentSchema } from './phrasing-content'; import { deepFilterHTML, - isPlain, - removeInvalidHTML, getBlockContentSchema, } from './utils'; -/** - * Browser dependencies - */ -const { console } = window; - -export { getPhrasingContentSchema }; - -/** - * Filters HTML to only contain phrasing content. - * - * @param {string} HTML The HTML to filter. - * - * @return {string} HTML only containing phrasing content. - */ -function filterInlineHTML( HTML ) { - HTML = deepFilterHTML( HTML, [ phrasingContentReducer ] ); - HTML = removeInvalidHTML( HTML, getPhrasingContentSchema(), { inline: true } ); - - // Allows us to ask for this information when we get a report. - console.log( 'Processed inline HTML:\n\n', HTML ); - - return HTML; -} +export { getPhrasingContentSchema } from './phrasing-content'; +export { pasteHandler } from './paste-handler'; function getRawTransformations() { return filter( getBlockTransforms( 'from' ), { type: 'raw' } ) @@ -110,137 +78,6 @@ function htmlToBlocks( { html, rawTransforms } ) { } ); } -/** - * Converts an HTML string to known blocks. Strips everything else. - * - * @param {string} [options.HTML] The HTML to convert. - * @param {string} [options.plainText] Plain text version. - * @param {string} [options.mode] Handle content as blocks or inline content. - * * 'AUTO': Decide based on the content passed. - * * 'INLINE': Always handle as inline content, and return string. - * * 'BLOCKS': Always handle as blocks, and return array of blocks. - * @param {Array} [options.tagName] The tag into which content will be inserted. - * @param {boolean} [options.canUserUseUnfilteredHTML] Whether or not the user can use unfiltered HTML. - * - * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. - */ -export function pasteHandler( { HTML = '', plainText = '', mode = 'AUTO', tagName, canUserUseUnfilteredHTML = false } ) { - // First of all, strip any meta tags. - HTML = HTML.replace( /]+>/, '' ); - - // If we detect block delimiters, parse entirely as blocks. - if ( mode !== 'INLINE' && HTML.indexOf( '