Roland Seuhs
Roland Seuhs

Reputation: 1995

How to paste rich text from clipboard to HTML textarea element?

When copy-pasting from a web-browser to a text-processor, the HTML-markup is converted into rich text and the text-processor tries to convert the markup into it's own format. This proves that the Clipboard is able to hold markup.

When copy-pasting between browser-windows (into a normal <textarea> or other element), then the markup is ignored, even though the markup exists in the clipboard.

Maybe there is a solution that makes the browser pick the rich text format from the clipboard.

Is there a way to access the rich text of the clipboard in an <textarea> element?

In other words,

Can the markup that has to be somewhere in the clipboard (because the clipboard does not know yet whether the user pastes into a text-processor or a web-browser) be pasted as-is into a HTTP POST variable?

Upvotes: 32

Views: 30390

Answers (6)

Jan
Jan

Reputation: 2249

Thank for excellent Chris Chalmer's answer, but what about making it a bit more complete ? I would prefer to add some padding and get code too... Tested in Edge, FF and Chrome and works even here ;-)

<div id="target" style="height: 75vh;border:1px solid gray" contenteditable="true">Paste here...</div>
<textarea style="height:25vh;width: 100%;"></textarea>
<script>
document.addEventListener('paste', function(e) {
    e.preventDefault();
    
    var pastedText = ''

    if (window.clipboardData && window.clipboardData.getData) { // IE

        pastedText = window.clipboardData.getData('Text');

    } else if (e.clipboardData && e.clipboardData.getData) {

        pastedText = e.clipboardData.getData('text/html');

    }

    var tmp1 = ["<div style=\"", "</div>",
        "<!--StartFragment-->","<!--EndFragment-->"]
    var tmp2 = [pastedText.indexOf(tmp1[0]) + tmp1[0].length, pastedText.lastIndexOf(tmp1[1])];
    if (tmp2[0] < 0 || tmp2[1] < 0) {
      tmp2 = [pastedText.indexOf(tmp1[2]), pastedText.lastIndexOf(tmp1[3])];
      tmp2[0] += tmp1[2].length;
      tmp2[1] -= tmp1[2].length;
      pastedText = pastedText.substr(tmp2[0], tmp2[1] - tmp2[0]);
      pastedText = pastedText.replace(/"/g,"'").replace(/&quot;/g, '"');
    } else {
      tmp2[0] += tmp1[0].length;
      pastedText = tmp1[0] + "padding:8px;" + pastedText.substr(tmp2[0], tmp2[1] - tmp2[0]);
    }
    tmp1 = document.getElementById('target');
    tmp1.innerHTML = pastedText;
    tmp1.nextElementSibling.value = pastedText;
});
</script>

Upvotes: 2

facechomp
facechomp

Reputation: 164

Paste to Google Docs, then click File >> Download >> Web Page (html, zipped)

Upvotes: -4

rokdd
rokdd

Reputation: 652

I personally looked for a solution to grab the rtf out of the clipboard and managed in this jsbin:

console.log(event.clipboardData.types);
let paste = (event.clipboardData || window.clipboardData).getData('text/rtf');

For assigning the content without escaping when inserting into a textarea (don't forget to update the querySelector + html):

target.value=paste

There are also other types like files or html available. I tested by copying it from Excel.

Upvotes: 0

Chris Chalmers
Chris Chalmers

Reputation: 614

I have been working on a similar problem: how to access the rich text formatting tags when pasting into the browser from a desktop application. I have found the following articles and have a solution that may solve your problem, though at the time of this writing it hasn't solved my own.

  1. https://www.lucidchart.com/techblog/2014/12/02/definitive-guide-copying-pasting-javascript/

  2. JavaScript get clipboard data on paste event (Cross browser)

If all you are looking for is the formatted html (a result of the browser having parsed the rich text for you), the answer is to access the clipboardData object and pass it the 'html' parameter instead of the 'text' parameter. see example below (just paste the following into a file called index.html and run it locally):

<div id="target" contenteditable="true"></div>

<script>
    document.addEventListener('paste', function(e) {
        e.preventDefault();
        
        var pastedText = ''

        if (window.clipboardData && window.clipboardData.getData) { // IE

            pastedText = window.clipboardData.getData('Text');

        } else if (e.clipboardData && e.clipboardData.getData) {

            pastedText = e.clipboardData.getData('text/html');

        }

        document.getElementById('target').innerHTML = pastedText
    });
</script>

The above example splits out two versions of clipboardData.getData(), one for IE and one for every other browser. The rough process is: first catch the paste event, then preventdefault, then get the clipboard data as html, then place it into the div. The content of this example is entirely stolen from the two links above, but simplified to exclude the extra things I didn't need (ie: hidden inputs to manage the browser's focus and suport for 'copy' and 'cut' events). Full credit should go to the authors of those articles.

In my experience (using mac and chrome) pasting formatted text (even with obscure formats like strikethrough and indent) into the #target div will keep the original formatting fairly well. Good Luck!

Now, if anyone can tel me how to get the actual rich text formatting tags from the clipboardData, please feel free to answer this question. Thanks!

Upvotes: 41

doc_id
doc_id

Reputation: 1433

The assumption that clipboard holds "HTML markup" is not correct. When you copy from a browser (or a window that utilizes Multiple Clipboard Formats) the window provides data in as many formats as possible. This includes Rich Text Format (RTF) and plain text. When you paste text, the desitination picks what it likes or what it can render. So a plain text box will pick the plain text, and your word-processor will prefer the rich text one, and defaults to the plain text copy.

EDIT: Some browsers -including Chrome > v.37 at least- may add source HTML as you copy content to clipboard. This is not a web standard thus unsafe.

Upvotes: 9

user2373071
user2373071

Reputation: 358

Google Office does support the RichText Format. When the text is copied from IE, IE copies to the clipboard in the plain text, rich text, and the html text. So copying from IE to Google office will show the rich formatted text. FireFox, on the other hand, only copies the text in the plain text and the html text format. So any target that does not accept the HTML formatted text will show the text in the plain text.

Upvotes: 0

Related Questions