Skip to content
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

Copy plain text variant of blocks #41366

Merged
merged 10 commits into from
Jun 15, 2022
Merged

Copy plain text variant of blocks #41366

merged 10 commits into from
Jun 15, 2022

Conversation

draganescu
Copy link
Contributor

What?

This PR strips the HTML from copied block markup for the text/plain version of the clipboard.

Why?

Pasting into plain text editors should only paste the text we see on screen not the whole underlying
markup.

This is an improvement in the experience of writing in a different app rather than in the
WordPress editor itself, and then bringing over the content. Since one could move text content back
and forth a few times, pasting block markup is annoying if not even prone to introducing problems.

How?

By fixing what seems to be a problem anyway: stripping HTML out of serialized data in the copy
handler before placing it in the text/plain version.

Testing Instructions

  1. Switch to this PR
  2. Create a post
  3. Copy the post content
  4. Paste in a plain text editor such as Notepat or Textedit (for Textedit make sure to use Format >
    Make plain text before pasting)
  5. Notice there is no block markup pasted

Screenshots or screencast

Before

paste-plain-before.mp4

After

paste-plain-after.mp4

@draganescu draganescu added [Type] Enhancement A suggestion for improvement. [Feature] Paste Needs Technical Feedback Needs testing from a developer perspective. labels May 26, 2022
@draganescu draganescu requested review from mcsf, adamziel and mtias May 26, 2022 08:12
@draganescu draganescu requested a review from ellatrix as a code owner May 26, 2022 08:12
@github-actions
Copy link

github-actions bot commented May 26, 2022

Size Change: +77 B (0%)

Total Size: 1.24 MB

Filename Size Change
build/block-editor/index.min.js 151 kB +75 B (0%)
build/edit-post/index.min.js 30.4 kB +1 B (0%)
build/edit-site/index.min.js 47.9 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.73 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 6.58 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/style-rtl.css 14.5 kB
build/block-editor/style.css 14.5 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 103 B
build/block-library/blocks/audio/style.css 103 B
build/block-library/blocks/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 514 B
build/block-library/blocks/button/style.css 514 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 95 B
build/block-library/blocks/comments/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 110 B
build/block-library/blocks/embed/theme.css 110 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 252 B
build/block-library/blocks/file/style.css 253 B
build/block-library/blocks/file/view.min.js 346 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.5 kB
build/block-library/blocks/gallery/style.css 1.49 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 333 B
build/block-library/blocks/group/editor.css 333 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 738 B
build/block-library/blocks/image/editor.css 737 B
build/block-library/blocks/image/style-rtl.css 524 B
build/block-library/blocks/image/style.css 530 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 705 B
build/block-library/blocks/navigation-link/editor.css 703 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.94 kB
build/block-library/blocks/navigation/style.css 1.93 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 393 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 69 B
build/block-library/blocks/post-comments-form/editor.css 69 B
build/block-library/blocks/post-comments-form/style-rtl.css 495 B
build/block-library/blocks/post-comments-form/style.css 495 B
build/block-library/blocks/post-comments/editor-rtl.css 77 B
build/block-library/blocks/post-comments/editor.css 77 B
build/block-library/blocks/post-comments/style-rtl.css 628 B
build/block-library/blocks/post-comments/style.css 628 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 605 B
build/block-library/blocks/post-featured-image/editor.css 605 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 369 B
build/block-library/blocks/query/editor.css 369 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 402 B
build/block-library/blocks/search/style.css 403 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 708 B
build/block-library/blocks/site-logo/editor.css 708 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 159 B
build/block-library/blocks/video/style.css 159 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 987 B
build/block-library/common.css 984 B
build/block-library/editor-rtl.css 10.2 kB
build/block-library/editor.css 10.2 kB
build/block-library/index.min.js 183 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.5 kB
build/block-library/style.css 11.5 kB
build/block-library/theme-rtl.css 677 B
build/block-library/theme.css 682 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 46.9 kB
build/components/index.min.js 227 kB
build/components/style-rtl.css 13.9 kB
build/components/style.css 13.9 kB
build/compose/index.min.js 11.7 kB
build/core-data/index.min.js 14.5 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.4 kB
build/customize-widgets/style.css 1.4 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 7.95 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.65 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4.03 kB
build/edit-navigation/style.css 4.04 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/style-rtl.css 7.05 kB
build/edit-post/style.css 7.05 kB
build/edit-site/style-rtl.css 7.69 kB
build/edit-site/style.css 7.67 kB
build/edit-widgets/index.min.js 16.4 kB
build/edit-widgets/style-rtl.css 4.39 kB
build/edit-widgets/style.css 4.38 kB
build/editor/index.min.js 38.1 kB
build/editor/style-rtl.css 3.63 kB
build/editor/style.css 3.62 kB
build/element/index.min.js 4.26 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.6 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.38 kB
build/list-reusable-blocks/index.min.js 1.74 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.89 kB
build/notices/index.min.js 945 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.51 kB
build/token-list/index.min.js 662 B
build/url/index.min.js 3.61 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@mtias
Copy link
Member

mtias commented May 26, 2022

cc @mcsf who has thought about these mechanics before

Copy link
Contributor

@mcsf mcsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value in this change is clear, but we need to identify the use cases for stripped and unstripped content copying, so as to minimise the disruption for users who have come to expect this behaviour. :)

Btw, I quickly wrote and uploaded a "clipboard debugger" to dive into this topic: http://mcsf-clipboard-data.surge.sh/ . This works as expected in Firefox, but I see strange data in Safari, which I suspect to be due to some policy of per-domain clipboard isolation or similar.

So, coming back to identifying use cases, we have:

  1. Select a range of blocks and copy with Meta+C — handled by CopyHandler
  2. Select a range of rich text within a single block and copy with Meta+C — handled by useCopyHandler
  3. Click the Copy All Content button in the More menu — handled by CopyContentMenuItem
  4. Select a block and click the Copy button in the block's dropdown menu — handled by CopyMenuItem
  5. (anything else that I'm forgetting?)

The first two cases are those in which multiple types of data are added to the clipboard (text/plain, text/html, and some special rich-text-related types), while in cases 3 and 4 we only set text/plain with serialised block markup.

Case 1 is the one that this PR is changing. Note that, in case 2, the plain-text payload was already free of the HTML-comment block demarcations, so this PR can be said to make copying more consistent across the editor.

@draganescu: Can we list pros and cons of stripping content down to the visible plain text?

event.clipboardData.setData( 'text/plain', serialized );
event.clipboardData.setData(
'text/plain',
stripHTML( serialized )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go forward with this, we'll want to clean up line breaks:

Suggested change
stripHTML( serialized )
stripHTML( serialized ).replace( /\n\n+/g, '\n\n' )

I'm trying to decide whether this belongs inside stripHTML; it's a question of whether it can break any expectations within Gutenberg Core, and — although it's an explicitly __unstable API — any expectations with third parties.

@mcsf
Copy link
Contributor

mcsf commented May 27, 2022

Years ago, in a discussion in this repo around copying and pasting, someone suggested some sort of just-in-time UI, like a popover around the cursor, asking the user what they would like to copy or paste: the plain text, the rich text, or the markup.

I don't really know how I would find that thread nowadays; I don't think that anything came of it, but I think there's an opportunity for better clipboard ergonomics.

In my mind, it's similar to this URL-opening tool called Choosy, but reacting to Meta+C or Meta+V:

open-link-with-choosy.mp4

@mtias
Copy link
Member

mtias commented May 27, 2022

Years ago, in a discussion in this repo around copying and pasting, someone suggested some sort of just-in-time UI, like a popover around the cursor

Me! Ulysses does something similar.

@draganescu
Copy link
Contributor Author

Wow, we're handling the clipboard in so many places 😁 !

Can we list pros and cons of stripping content down to the visible plain text?

Pros

  • Pro: the user pastes visible text in apps that expect to receive just that, visible text. It's hard to argue that I copy visible text in WordPress paste in Notepad and expect a soup of JSON and HTML, plus the visible text.
  • Pro: we are not lying to the computer, if we say we set text/plain then this is what we place there.
  • Pro: we're not encouraging manual editing on block HTML. When we paste in an app that takes rich text or HTML, the user visually edits the content and when it pastes back to Gutenberg, we can trust our platform for the correct transformation. With block markup and HTML in plain text we have no guarantees over what we're getting, we don't have a super solid auto fixing system and even what is wrong is hard to highlight. So better safe than sorry.
  • Pro: it matches other systems and tools - pasting rich media and rich formatting text from Google Docs or MS Word in a plain text app results in visible text being pasted, nothing else.

Cons

  • Con: may be confusing if unexpected - pasting plain text not only loses the formatting but also the media. This would only happen if the capabilities of the destination application are unknown to the user, which is not for WP to solve.
  • Con: some applications don't handle clipboard objects well and default to text/plain if that is preset. This is a bug to be fixed in those applications.

a popover around the cursor, asking the user what they would like to copy or paste: the plain text, the rich text, or the markup.

MS Word has the Paste Special command which opens an ancient popup window allowing the user to select what to paste (HTML, formatted, unformatted).

identifying use cases

To make things consistent I think we should:

(a) make the behavior of:

  • Select a range of blocks and copy with Meta+C
  • Select a range of rich text within a single block and copy with Meta+C
  • Select a block and click the Copy button in the block's dropdown menu

... be consistent in putting visible text in text/plain and html + block markup in text/html, plus the formatted rich text.

(b) rename the more menu's "Copy All Content" to "Copy Block Content" and override text/plain with block markup and HTML in this special situation, which would be a shortcut to switching to code view and copying all visible text from there.

@mcsf
Copy link
Contributor

mcsf commented May 31, 2022

I think your arguments and proposals are fair, @draganescu. I'd like an extra opinion, perhaps from @ellatrix?

@ellatrix
Copy link
Member

ellatrix commented Jun 8, 2022

This is fine with me. Ideally, the plain text type should be plain text, the HTML type should be just HTML without block demarkations, and we should use a custom type for the proper serialised output with the block demarkations.

I'm pretty sure there's at least one existing issue that can be closed by this PR?

@draganescu
Copy link
Contributor Author

@mcsf @ellatrix so what's next for this? Can it be merged like this, or should I build the following:

(a) make the behavior of:

Select a range of blocks and copy with Meta+C
Select a range of rich text within a single block and copy with Meta+C
Select a block and click the Copy button in the block's dropdown menu

... be consistent in putting visible text in text/plain and html + block markup in text/html, plus the formatted rich text.

(b) rename the more menu's "Copy All Content" to "Copy Block Content" and override text/plain with block markup and HTML in this special situation, which would be a shortcut to switching to code view and copying all visible text from there.

... on top of this?

@ellatrix
Copy link
Member

ellatrix commented Jun 8, 2022

plus the formatted rich text

Not sure what you mean here.
Yeah, everything should be consistent in all our copy events
Should we add e2e tests?

@mcsf
Copy link
Contributor

mcsf commented Jun 9, 2022

If I understood Ella correctly, the part about allowing users to copy HTML stripped of block demarcations into text/html is something to consider after this PR, not in it. But, as for the rest, I believe it should all be in this PR:

  • copy consistency per item (a)
  • e2e tests
  • (optionally here, or subsequently) renaming of the Copy All Content button per item (b)

@draganescu
Copy link
Contributor Author

Some complexity here :)

Screenshot 2022-06-10 at 19 14 20

@draganescu
Copy link
Contributor Author

@mcsf for consistency the following have been added:

  • I added a small UI label improvement to block tools, to use plural "blocks" if multiple are selected
  • I changed the editor (post and site) label for "Copy content" to "Copy all blocks" which is to make a connection that the block tools copy is similar to editor tools copy, and results in block markup being copied as plain text.
  • I updated the plain text setter for useClipboardHandler to remove multiple consecutive new lines. I opted to have it just here and not update the exposed stripHtml api.
  • I have added a test to guard against pasting block content in plain text contexts, by using a code block. I think it work for our purpose.

Copy link
Contributor

@mcsf mcsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this just needs the _n fix (feel free to commit the suggestion from GH) and is good to go.

@draganescu
Copy link
Contributor Author

:D eferenceError: _n is not defined I felt too free to commit from GH.

@mcsf
Copy link
Contributor

mcsf commented Jun 13, 2022

:D eferenceError: _n is not defined I felt too free to commit from GH.

What, it doesn't run? Pff, minor detail! 😅

@draganescu draganescu force-pushed the try/better-text-copy branch from 6af62cc to 89006fd Compare June 15, 2022 08:15
@draganescu draganescu merged commit 6f3bb8c into trunk Jun 15, 2022
@draganescu draganescu deleted the try/better-text-copy branch June 15, 2022 09:22
@github-actions github-actions bot added this to the Gutenberg 13.5 milestone Jun 15, 2022
@gaambo
Copy link
Contributor

gaambo commented Jun 29, 2022

FYI: I worried that this change might break the possibility to copy multiple blocks / nested blocks to save them in a .html file for including as a pattern in a theme. But using the "Copy Block" menu button and pasting it into VSCode or Windows Notepad also pastes the block markup - so everything's fine 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Paste Needs Technical Feedback Needs testing from a developer perspective. [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants