29

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?

Roland Seuhs
  • 1,878
  • 4
  • 27
  • 51

5 Answers5

37

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!

Thor-x86_128
  • 157
  • 18
Chris Chalmers
  • 574
  • 4
  • 13
  • I'm pretty sure if you change `$("#target").html(pastedText);` to `$("#target").text(pastedText);` it should work just fine. I made a similar non-jquery example. When I set innerHTML of the element, it formatted the html. When I set innerText of the element, it gave me the tags. – Eric Dauenhauer Jun 01 '17 at 20:43
9

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.

doc_id
  • 1,363
  • 13
  • 41
  • 2
    Thanks for the explanation. Thus, how can I access the RTF-format then? How can I make the browser pick the RTF instead of the plain text? – Roland Seuhs Mar 17 '15 at 10:43
  • @Roland Seuhs, I though flash would have been the solution for you but "The RTF markup is not interpreted or translated in any way." : http://help.adobe.com/en_US/as3/dev/WS0579B9EE-CF1E-434e-A386-A04DC7786FC9.html – Kaiido Mar 17 '15 at 11:33
  • Very sad. What happens when one pastes into Google-office? Maybe they have found a solution or workaround. If not, I would think that is a major limitation of Google-office. – Roland Seuhs Mar 17 '15 at 13:26
  • @RolandSeuhs you can create a div with `contenteditable` attribute. This will make the DIV editable so that when a user *paste* content into, it will pick the RTF and _convert_ it to HTML. Thus, the resulting HTML is not guaranteed to match the original markup on which the copy was performed. Note that I say "not guaranteed" but it's *possible* that the clipboard holds an HTML copy and that depends on how the browser fills the clipboard. – doc_id Mar 18 '15 at 09:18
  • This demonstrates the contenteditable http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_global_contenteditable In Chrome for example, if you copy any part in the page and paste into that div, it will keep the HTML. This may not a standard with other browsers. – doc_id Mar 18 '15 at 09:27
  • That looks very promising - is there a way to copy the contents with Javascript to a `` element so that it will be included as a POST variable? – Roland Seuhs Mar 19 '15 at 15:05
  • If the hidden element has id "html" and the div with `contenteditable` has id "ed" `document.getElementById("html").value = document.getElementById("ed").innerHTML` – doc_id Mar 19 '15 at 18:30
2

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: 75%;border:1px solid gray" contenteditable="true">Paste here...</div>
<textarea style="height:25%;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>"];
        var tmp2 = [pastedText.indexOf(tmp1[0]) + tmp1[0].length, pastedText.lastIndexOf(tmp1[1])];
        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>
Jan
  • 2,178
  • 3
  • 14
  • 26
1

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.

user2373071
  • 310
  • 5
  • 10
0

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.

rokdd
  • 541
  • 4
  • 14