[whatwg] Sync/async drag-and-drop data and Blob

I've been thinking about how to extend DataTransfer to support non-text
types, such as images or RTF. Some use cases that this would enable:
- Copying and pasting images between Photoshop and a web-based image editing
app such as http://canvaspaint.org/.
- Copying a slide with inline pictures from a presentation and pasting it
into an email without losing any of the formatting.

Since the data might be in text or binary form, I propose adding Blob
support to DataTransfer. The proposed additions would add the following two
functions to DataTransfer:
Blob getDataAsBlob(in DOMString format);
void setDataAsBlob(in DOMString format, in Blob data);

Callers would use it like this:
<script>
document.addEventListener('paste', function (event) {
  var imageBlob = event.dataTransfer.getDataAsBlob('image/png');
  var reader = new FileReaderSync();
  var newImage = document.appendChild(document.createElement('img'));
  newImage.src = reader.readAsDataURL(imageBlob);
});
document.addEventListener('copy', function (event) {
  var bb = new BlobBuilder();
  bb.append(someFunctionThatConvertsAnImageSelectionToAnArrayBuffer());
  event.dataTransfer.setData('image/png', bb.getBlob());
});
</script>

By using Blob, callers have the freedom to pick a synchronous or
asynchronous model. For example, to avoid blocking the page, an image
editing app might choose to read pasted image data asynchronously in a
callback:
<script>
function onImageLoaded(event) {
  // Do something with the event.target.result.
}
document.addEventListener('paste', function (event) {
  var imageBlob = event.dataTransfer.getDataAsBlob('image/png');
  var reader = new FileReader();
  reader.onload = onImageLoaded;
  var newImage = document.appendChild(document.createElement('img'));
  reader.readAsDataURL(imageBlob);
});
</script>

In addition, getData() and setData() could be redefined to be based on the
two new functions:
DataTransfer.prototype.getData = function (format) {
  var reader = new FileReaderSync();
  var blob = this.getDataAsBlob(format);
  return reader.readAsText(blob);
};
DataTransfer.prototype.setData = function (format, data) {
  var builder = new BlobBuilder();
  builder.append(data);
  this.setDataAsBlob(format, builder.getBlob());
};

One issue that I'm not clear how to resolve is the issue of Blob.size. In
general, the UA won't be able to populate Blob.size without reading in all
the data first... which defeats the point of using Blob to begin with. Since
people may not read Blob.size very often in the context of copy-and-paste or
drag-and-drop, maybe it's acceptable to lazily populate Blob.size only if
people try querying its value? People who want async behavior won't truly
get it if they query Blob.size, but I don't see another way around the
problem.

Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20101029/22552337/attachment.htm>

Received on Friday, 29 October 2010 15:31:19 UTC