Telerik blogs

Pasting images in RadEditor and converting the src attribute into base64 format was possible only in Firefox, but not anymore. Now it can be done in Chrome too. How did we make it happen? Here is the basic story, without all the blood and sweat shed along the way.

A little background check

As you may know (especially if you have asked our support team), pasting an image from MS Word into an editable IFrame or a HTML editor, when using a browser other than Firefox, does not work as expected. The image src points to some temp file like

<img src="file:///C:/Users/NSTOYC~1/AppData/Local/Temp/1/img002.gif" />

Thus, loading the image from different location fails.

Until now, only Firefox converted the src into base64 format, which makes the image available for later usage from different locations, because it embeds the entire image in the markup, instead of referencing it from an URI:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

That is a simple red dot Red dot.

What is also important to note is that this works only with single image.

How we did it in Chrome

To achieve this feature, we handled the paste event and retrieved the clipboardData object from it, which represents the contents of the clipboard as an array of items (DataTransferItemList). Each item has a type and we can check that type for an image:

getImages: function(event)
{
    var items = event.clipboardData.items;
    for (var i = 0; i < items.length; i++)
    {
        if (items[i].type.indexOf("image") != -1)
        {
            var image = _getImage(items[i]);
            if (image) //paste the image
        }
    }
},

What makes this tricky is that the data passed is highly browser-dependent and currently only Chrome offers this information to the developer.

Here is the paste event object structure:

Chrome clipboardData object on paste

Then we convert the item with the image to a blob. The blob object is a file-like representation of the raw data that we received in the clipboard. Using the blob and window.URL, we can call createObjectURL, which will create a unique object URL. The object URL is a string that identifies the File object.

var blob = item.getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
var image = new Image();
image.src = source;

Now the image src looks something like:

<img src="blob:null/e77b0e3e-df9a-481c-a900-ee5b85f36b1c"/>

The lifetime of the object URL is tied to the document in the window on which it was created, like every object URL. In other words, the image will be available in the current browser until it is closed. Now, we can convert the file object our src points to in base64 format.

To do this, we handle the image onload event, create a FileReader, handle the FileReader onload event and get the event.target.result from the reader load event, which is the file converted into base64 format.

image.onload = function(ev)
{
    var reader = new FileReader();
    reader.onload = function(e)
    {
        image.src = e.target.result;
    };
    reader.readAsDataURL(blob);
}
return image;

Where the readAsDataURL() method initiates the reader loading process, so that when it finishes the onload event will fire and we can get the base64 string.

Sounds complicated? Well, it is, and this here is the final concept that was achieved through a lot of research and efforts. It may look like a few lines of code, but getting this all tied up together is not an easy job, I can assure you.

Why did we put so much effort into this

We have been receiving a constant stream of questions regarding this feature. Put shortly, people wanted it to work everywhere like in Firefox. Our clients want their clients to be able to simply copy their MS Word documents in RadEditor without much hassle (so we greatly improved the Paste from Word functionality with the Q1 2013 release). Now we added another member to the conversion family – you can paste your images piece by piece in Chrome as well. With these two major browsers covered one could say that about 80% of the users can now paste an image in RadEditor, right :)

What’s next

Do you want to drag images from your local machine directly in RadEditor and have them paste all at once? Because we can do it, under Chrome.

We have some other great ideas about the future of our Editor control, and we want to hear what you think.  Does this paste functionality help you?  What functionality are you looking for in an editor?

 Add a comment below, send us a ticket, start a forum thread or directly post in our Feedback portal. Your input is valuable and greatly influences our development plans.


Marin Bratanov
About the Author

Marin Bratanov

Marin Bratanov was a Principal Technical Support Engineer in the Blazor division.

Comments

Comments are disabled in preview mode.