Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access pasted file in webkit browsers? (as Google Chrome)

It would be very convenient if one was able to paste images here, on Stack Exchange instead of meddling with a file dialog. Similar feature was (is?) implemented here, but only for Webkit browsers.

I was developing userscript that does that. Funny thing is that I never accomplished to get the file (which is different from raw image data) from clipboard in Webkit browsers, while in Firefox it works.

Firefox solution:

  div.addEventListener('paste', function(event){
    //I'm actually not sure what should event.originalEvent be. I copypasted this
    var items = (event.clipboardData || event.originalEvent.clipboardData);
    console.log("paste", items);
    //Try to get a file and handle it as Blob/File
    var files = items.items || items.files;
    if(files.length>0) {  
      //Being lazy I just pick first file
      var file = files[0];
      //handle the File object
      _this.processFile(file);

      event.preventDefault();
      event.cancelBubble = true;
      return false;
    }
  });

Before Chrome doesn't have as nice documentation as Firefox has (I mean MDN), I tried to inspect what's going on. I copied a file and I pasted it in Google chrome (v39). This is what I get in the DataTransfer object in the console:

paste event Google chrome

For refference, here's the same event in Firefox:

paste event files firefox

The other two arrays, items and types are not present in Firefox implementation. When I copy text or raw image data Chrome represents it as DataTransferItem. I figured out that it's best to ignore those:

  //Being lazy I just pick first file
  var file = files[0];
  //GOOGLE CHROME
  if(file.getAsFile) {
    console.log("DataTransferItem:", file);
    //HTML or text will be handled by contenteditable div
    if(file.type!="text/plain" && file.type!="text/html") {
      //handle the File object
      _this.processFile(file.getAsFile());
    }
  }
  else 
    ...

So far, I never occurred to get anything else than text/plain or text/html. For these, .getAsFile returns null.

I find the google chrome model a little confusing. It gives you more info about raw data (text/raw image), which can only be accessed using content editable div, but isn't very clear to me.

like image 907
Tomáš Zato - Reinstate Monica Avatar asked Dec 03 '14 02:12

Tomáš Zato - Reinstate Monica


1 Answers

Our magic sauce is just:

$('body').bind('paste', handlepaste);

Where handlepaste is very similar to yours, so should work for you just fine for Chrome.

Unfortunately the above completely fails for FF, and we are loath to add a contenteditable anywhere (in particular given that it has to be in focus for this to work and we don't want to steal the focus).

like image 159
Oded Avatar answered Sep 22 '22 13:09

Oded