-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Fix: Pasting a tag that is part of a transform and not matched ignores the content. #11244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Pasting a tag that is part of a transform and not matched ignores the content. #11244
Conversation
|
Could (integration) tests be added? |
|
Hi @iseulde, |
3c7b4a7 to
d33a274
Compare
|
|
||
| return; | ||
| return createBlock( 'core/html', { | ||
| content: originalPieceFiltered, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't quite right. We will want to return the HTML of the current node here, not the entire piece.
return createBlock( 'core/html', {
content: node.outerHTML,
} );You can see this bug by:
- Create a new post
- Run
wp.blocks.unregisterBlockType( 'core/preformatted' )in the console - Copy the entire text of this comment including the code snippet above
- Paste it into Gutenberg
Only the code snippet above should appear as a HTML block. Instead, the entire comment appears in the HTML block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Moving out of 4.3 as it doesn't seem urgent or ready. |
d33a274 to
e6ef9c6
Compare
|
I applied a series of changes to this PR, the problems identified should be fixed. |
|
I tested and confirmed that it works as advertised but I'm not sure I understand why we create a paragraph block instead of an HTML block like suggested initially? |
|
Hi @youknowriad, Our algorithm when we find some tag that we don't handle is to parse the children inside it as if the tag did not exist. The previous approach of returning HTML was not possible because it created a bug as @noisysocks discovered even if we are pasting content that can be handled (together with non matched content) our algorithm was not executed and we were just returning giant HTML block. |
This feels like the algorithm should be reversed so that we consider this as a fallback or something but granted I don't know enough about it to say whether it's possible/good ... |
|
I think it needs a rebase after #12029. What issues are fixed here that that PR doesn't fix? |
e6ef9c6 to
57e4527
Compare
|
Hi @iseulde, this PR was rebased. The bug is that if a given tag is only accepted because a block set a raw handler for it, but then is not matched on isMatch function we loose content. |
| if ( ! objValue || ! srcValue ) { | ||
| return undefined; | ||
| } | ||
| return ( ...args ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to comment on this? It's hard to follow this if right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A description of the overall flow of the mergeWith call would help too.
| schema[ tag ].attributes.push( 'id' ); | ||
| } | ||
| } | ||
| if ( isMatch ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. Would it be possible to comment.?
| if ( schema.hasOwnProperty( tag ) ) { | ||
| if ( | ||
| schema.hasOwnProperty( tag ) && | ||
| ( ! schema[ tag ].isMatch || schema[ tag ].isMatch( node ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, let's leave a comment?
ellatrix
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me. Would love some more inline comments.
57e4527 to
9e01f2e
Compare
the problem raised was addressed
| // If an isMatch function exists add it to each schema tag that it applies to. | ||
| if ( isMatch ) { | ||
| for ( const tag in schema ) { | ||
| schema[ tag ].isMatch = isMatch; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this mutating the block type? Should it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mcsf, the transforms passed to this function are always the result of getRawTransformations and this function copies the transforms, so we are mutating that copy and not the block type.
https://github.com/WordPress/gutenberg/blob/master/packages/blocks/src/api/raw-handling/index.js#L57-L65
This function was already mutating the input, but I think given that it is a getter it is unexpected that this function mutates the input and I will open a follow-up PR that removes the mutations.

Fixes: #11057
On #11057 @jrmd discovered that if we remove the preformatted block (wp.blocks.unregisterBlockType('core/preformatted')) when pasting some content inside the pre tag e.g
<pre>Pre</pre>the content is simply ignored.What happens is that we have other blocks that implement a transform for the PRE tag (the code block) but simple pre-content is not matched by the code block raw handler so in this case, we just returned nothing and ignored the content.
This PR changes the situation when a tag contains a transform that handles it but does not match its content we now create an HTML block to contain that content (filtered to make sure it is something the user can insert on the site).
How has this been tested?
I removed the preformatted block
wp.blocks.unregisterBlockType('core/preformatted').I pasted some HTML content inside a PRE tag e.g:
<pre>Pre</pre>and checked it was added inside an HTML block.