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

fix: pasting in table #1181

Merged
merged 1 commit into from
Oct 30, 2024
Merged

fix: pasting in table #1181

merged 1 commit into from
Oct 30, 2024

Conversation

YousefED
Copy link
Collaborator

fixes this issue:

Kapture.2024-10-21.at.12.14.32.mp4

I also tried to fix #1077 at the same time, (this happens when trying to paste HTML content that's more than a single element, but this is quite a bit more involved unfortunately,

Copy link

vercel bot commented Oct 24, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
blocknote ✅ Ready (Inspect) Visit Preview Oct 24, 2024 11:56am
blocknote-website ✅ Ready (Inspect) Visit Preview Oct 24, 2024 11:56am

@mwonng
Copy link
Contributor

mwonng commented Oct 25, 2024

Hey @YousefED, i did find anything paste into block will actually create a new block(another line), this seems a default action. I did test both plaintext and html text from clipboard, it all go straight to another line. This seems against common user behaviour.

For example, if you selection in one of the block after a word, if you paste some plain text, it still create another block after current block instead of append current text selection. I'm not sure if BlockNote suppose to do past like this, but if not this could still be a problem for pasting.

I can see this fix apply table so it wont able to break table anymore.

It might be take care more action if it is a plain text and selection in a block it need to be append. this can be done in paste plugin in paste() call to identify the clipboard source as well.

Recording:
https://github.com/user-attachments/assets/e2632c58-343c-40ea-9dee-0ada8d1c84fb

@mwonng
Copy link
Contributor

mwonng commented Oct 25, 2024

for what i mentioned below, you can add this part code to fix to avoid auto create new block/lines

packages/core/src/api/clipboard/fromClipboard/pasteExtension.ts

paste(_view, event) {
    // rest code in past()
    // if (format === "text/html") {
    //   ...other code
   // }
    if (format === "text/plain") {
      editor._tiptapEditor.view.pasteHTML(data);
      return true;
    }

    // this is existed code
    editor._tiptapEditor.view.pasteText(data);
    return true
}

this should fix some other paste issue as well :)

@YousefED
Copy link
Collaborator Author

YousefED commented Oct 25, 2024 via email

@mwonng
Copy link
Contributor

mwonng commented Oct 25, 2024

for now, if you paste anything plain text, it will default insert another block and break current block into 2 blocks, {I} is caret/cursor position
e.g.

+ block {I}paragraph    <--- selection is between 'block' and `paragraph`

in this case, if i paste any thing, it will become

+ block
+ {something from your clipboard}
+ paragraph 

I'm not sure is this intend or not, but if it is not, you can add this part code

if (format === "text/plain") {
      editor._tiptapEditor.view.pasteHTML(data);
      return true;
 }

to make paste as inline paste (which i think more nature)

update: try to copy something plain text only.

@mwonng
Copy link
Contributor

mwonng commented Oct 25, 2024

maybe i need some more clarify sorry for confusion.
you can try to paste anything to this website to see clipboard

the screenshost show one with HTML(with style,text/html we usually copied from website), and another with plain text(with text/plain only, which usually copied pure plain text, you can copy plain text simply from address bar)

so when you copy plain text and paste into BlockNote, it will actually break lines.

This is not related to table specifically, your code should already fix paste inside table, but it act as default for some scenario(break the block), but i think my suggestion code can be in another PR for pasting as well

Snipaste_2024-10-26_01-20-32

Snipaste_2024-10-26_01-20-19

@mwonng
Copy link
Contributor

mwonng commented Oct 25, 2024

I think this paste issue might be more than it is, i also met this issue in my previous job. so I will try to list as possbile.

Paste into table is simple but the content in clipboard might be various, it could be:

  • inline rich text (span/p)
  • block rich text (heading/div) including end or \n
  • list rich text (ul/ol list more than one line)

Those all rich text, but for different reason it might be act as different behaviour. e.g inline rich text mostly work well with the fix only parseHTML. but for others and possible some other scenarios i didnt mentioned, it still able to break the block(including table), and at the same time it still need to think about if we need to default paste content into a new block and when.

In my previous work we do actually parse clipboard and reformate to another slice and dispatch the transaction.(it more than 700 lines code ONLY in paste() to handle most scenarios 😂)

Just FYI.

@mwonng
Copy link
Contributor

mwonng commented Oct 26, 2024

Investigation

UPDATE: video and explaination: https://www.loom.com/share/e0c9533be0e44d338d3bb96d7cd6cf6c

after i have a lot of test, i think i fount the issue, it might be a little complex to explain and these might need to related to some feature if BlockNote able to support:

The core it need to be think about:

  1. What types of nodes BlockNote want to support in table cell

When you copy something, the HTML node will be parse into editor node, when it recongnise as a inline node, it will be paste properly, such as copy of a span, or part of paragph.

When you copy something HTML it could be parse into a block. e.g. heading, list, etc, it will be parse into a Editor node directly.

As i tested, when your clipboard has HTML and it will able to be parse into a block, it will break the current block into two. otherwise it will keep the block and do a inline paste.

For this change you can still see if you copied a heading HTML into table cell, e.g. h1, h3 tag, it will still break the table.

This clipboard in text/html below will NOT break because this is recongized as span tag(which is inline).

<html>
<body>
<!--StartFragment--><span style="color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(246, 248, 250); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">ve safari variant (</span><a href="https://github.com/kiwicom/orbit/commit/6a0b77fbb1f881fd82a9ebf5ad870080a3fc9823" style="box-sizing: border-box; background-color: rgb(246, 248, 250); color: var(--fgColor-accent, var(--color-accent-fg)); text-decoration: underline; text-underline-offset: 0.2rem; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal;">6a0b77f</a><span style="color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(246, 248, 250); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">)</span><!--EndFragment-->
</body>
</html>

This clipboard in text/HTML below WILL break because this is recongized as h3 tag.

<html>
<body>
<!--StartFragment--><h3 style="box-sizing: border-box; margin-top: var(--base-size-24); margin-bottom: var(--base-size-16); font-size: 1.25em; font-weight: var(--base-text-weight-semibold, 600); line-height: 1.25; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">BREAKING CHANGES</h3><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 0px !important; color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, &quot;Noto Sans&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><br class="Apple-interchange-newline"><!--EndFragment-->
</body>
</html>

Example:

Copy this word not break.

copy 'this word' ^^^above^^^, note:only two words, not the whole line

Warning

If triple click to copy whole line, paste will also break .

this heading will break

copy 'this heading' or the whole line ^^^ above ^^^.

What should do about paste?

It need to be consider when pasting:

  1. What kind of HTML should be parse into block directly, e.g. heading, code, image, file, video etc.
  2. What kind of HTML should be parse inline so it paste inline, e.g. span, paragrah etc.
  3. What kind of HTML need to be pre-procecss before do a real pasting, e.g. copied part of the list(not whole ul tag, part of li tag)

Sorry i write a lot of stuff here, i understand paste is pretty trick part of editor and it also act different in Chrome and FireFox when copy the samething. It still need to be consider if BlockNote want a better user expeirence.

Back to this case, I would say, maybe treat all paste in table as a plain text might be the better option for now.

@YousefED
Copy link
Collaborator Author

thanks for the comments @mwonng , for now I'll go ahead and merge this fix and will continue later with #1077

@YousefED YousefED merged commit 08b5510 into main Oct 30, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

when past rich text on table cell, the table is broken
2 participants