6

Note: I'm adding information I discover that seems to be leading to a resolution in the note.

The Problem:

When pasting content from outside of Gutenberg (e.g., Google Docs) into Gutenberg, some formatting is lost. Gutenberg retains HTML (semantic) elements but drops styling by CSS, etc. This means colors, alignment, and other similar properties are not transferred into Gutenberg.

Not the Problem:

We could discuss the plugins, custom HTML blocks, etc. (e.g., Wordable, WordPress.com/JetPack plugin) available for converting external content sources (e.g., Google Docs) to WP friendly content but this question is decidedly not about those solutions. Instead, this question is exclusively focused on how to programmatically alter Gutenberg's paste handling behavior.


Relevant Code in Gutenberg Core:

pasteHandler Function

The behavior appears to occur in the pasteHandler function found in:

packages/blocks/src/api/raw-handling/paste-handler.js

This function takes five parameters:

  • HTML = The source content to convert if in HTML format
  • plainText = The source content to convert if in text format
  • mode = Whether to paste the content in as blocks or inline content in existing block.
  • tagName = What tag we are inserting the content into.
  • canUserUseUnfilteredHTML = Whether the pasteHandler will strip out some elements or let everything be pasted in.

The last parameter is the one we are concerned with here. By default, it is set to false - that is, the pasteHandler will strip out specific elements and will not allow all elements to be pasted in.

An Individual Component's Code:

We can find individual components in:

/packages/block-editor/src/components/

Lets look at rich-text. We can see that pasteHandler is imported (index.js):

import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform, isUnmodifiedDefaultBlock } from '@wordpress/blocks';

pasteHandler is then called from onPaste:

onPaste( { value, onChange, html, plainText, files } ) {

...

if ( files && files.length && ! html ) {
  const content = pasteHandler( {
    HTML: filePasteHandler( files),
    mode: 'BLOCKS',
    tagName,
} );

...

const content = pasteHandler ( {
  HTML: html,
  plainText,
  mode,
  tagName,
  canUserUseUnfilteredHTML,
} );

...

}

What I'm still unsure of is how to modify parameters that are passed either within an individual component (index.js of component) or at the underlying pasteHandler level. Any thoughts?


Side Notes:

Is This Only a Google Docs/Microsoft Word Problem? (No)

This problem is not limited to sources like Google Docs or Microsoft Word, which are known to add extraneously (at least for adding to Gutenberg) code, and it also happens with manually crafted HTML. For example, try pasting the following into a paragraph block:

<p style="color:red">Hello WordPress StackExchange!</p>

Take a look at the HTML behind the block, and you'll see:

<p>Hello WordPress StackExchange!</p>

The style="color:red" has been stripped.

This question had a bounty worth +50 reputation from davemackey that ended 7 hours ago. Grace period ends in 16 hours

This question has not received enough attention.

  • Is it possible that data isn't in the clipboard? If you know a way to keep that data given an appropriate mechanism, I think the GB team would quite like the contribution so all users can benefit, I'd be curious how myself – Tom J Nowell Nov 7 at 22:12
  • @TomJNowell - I used a small app called ClipView to see the raw content of my clipboard and the CSS is present. Also, based on some conversations in Github issues it seems the decision was made to strip the CSS and retain only semantic (HTML) content. – davemackey Nov 7 at 22:30
  • Did you take a look at this part of the docs already? – Cas Dekkers Nov 12 at 23:10
  • Hi Cas, I did. The docs are pretty sparse. – davemackey yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.