Preventing Pasting of Images in CKEditor
In the process of developing our XPages ‘Webmail’ interface, we discovered that many recipients were unable to view embedded images in the emails.
After investigating, it was caused by the images being embedded using Data URIs. Support for Data URI Images is not universal, and because it is supported in IBM Notes, everything looked like it was working ok, but a quick test viewing an email in Gmail confirmed a problem when images could not be seen.
What is a Data URI?
You are most likely familar with an image being specified by a URL to Resource, in this cause all the binary data for the image is requested from some location
1 |
<img src="reddot.png" alt="Red dot" /> |
With a data URI, all the binary data for the image is contained directly in the src=”” attribute, and does not need to be requested from anywhere, here is an example I lifted from wikipedia:
1 2 3 |
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" /> |
When sending emails however, it is a much better idea to embed the image as a separate mime entity, and refer to it using a ‘Content Identifier’ (cid).
1 |
<img alt="" src=cid:reddot_1479074021464></img> |
The image data is then retrieved from the related mime entity which specifies that Content-ID as a MimeHeader
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--==IFJRGLKFGIR32748UHRUHIHD Content-Type: image/jpeg Content-Disposition: inline; filename="reddot_1479074021464.JPG" Content-ID: <reddot_1479074021464> Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQEAYABgAAD/4RD4RXhpZgAATU0AKgAAAAgABAE7AAIAAAAPAAAISodpAAQA ...more binary data... iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k= --==IFJRGLKFGIR32748UHRUHIHD-- |
Sending Embedded Images in Emails
The best format for sending emails is the ‘content-id’ method, and the Xpages CKEditor provides a toolbar button which will perform the image upload and attach asĀ separate mime entity.
On the other hand, an easy way for users to insert images is to use some screen capture software such as Snipping Tool and then copy and paste into the CKEditor. When this method is used, the image is inserted as a Data URI.
By default, some browsers don’t support the pasting of images anyway, but Firefox and probably some others do, and it must be stopped!
Preventing Pasting of Images using a CKEditor plugin
After a bit of googling I found that someone else had already come up with a plugin which prevents pasted images, and it worked without modification for XPages
I will repost the plugin here, the only modification I have made is the alert message to explain to the User to use the image upload toolbar button
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
CKEDITOR.plugins.add('blockimagepaste', { init : function(editor) { function replaceImgText(html) { var ret = html.replace(/<img[^>]*src="data:image\/(bmp|dds|gif|jpg|jpeg|png|psd|pspimage|tga|thm|tif|tiff|yuv|ai|eps|ps|svg);base64,.*?"[^>]*>/gi, function(img) { alert("Pasting Image Data is not allowed. Please use the Image Upload button (if available)."); return ''; }); return ret; } function chkImg() { // don't execute code if the editor is readOnly if (editor.readOnly) return; setTimeout(function() { editor.document.$.body.innerHTML = replaceImgText(editor.document.$.body.innerHTML); }, 100); } editor.on('contentDom', function() { // For Firefox editor.document.on('drop', chkImg); // For IE editor.document.getBody().on('drop', chkImg); }); editor.on('paste', function(e) { var html = e.data.dataValue; if (!html) { return; } e.data.dataValue = replaceImgText(html); }); } // Init }); |
To use the plugin, copy the above code into a Client Side JavaScript Library ‘blockimagepaste’.
Then, make sure to include the ScriptLibrary as a resource on your page. Also add the dojoAttribute ‘extraPlugins’ with the name of the plugin (from line 1 above ‘blockimagepaste’.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core"> <xp:this.data> <xp:dominoDocument var="document1"></xp:dominoDocument> </xp:this.data> <xp:this.resources> <xp:script src="/blockimagepaste.js" clientSide="true"></xp:script> </xp:this.resources> <xp:inputRichText id="inputRichText1" value="#{document1.body}"> <xp:this.dojoAttributes> <xp:dojoAttribute name="extraPlugins" value="blockimagepaste"></xp:dojoAttribute> </xp:this.dojoAttributes> </xp:inputRichText> </xp:view> |
So now when a user attempts to paste an image it will not be completed, and they will be given the alert
Summary and Next Steps
So in this post we added a CKEditor plugin to our application, and configured our InputRichText to use it.
The plugin prevents the pasting of data URI images, however you could modify this to prevent any html you like, in a future post we will show a modified version of this plugin to prevent images pasted using URLs. This can be troublesome for emails, as users may copy and paste html from internal applications, which is then not available to external email recipients.
Also, copying and pasting images is actually quite a useful feature don’t you think? our users did too, so we also implemented another plugin which intercepts the pasted image, and uploads it using the normal ‘Content-ID’ method instead, I will share that solution as well in a future post.
3 Responses
[…] Preventing pasting of Data URI images […]
[…] the previous post, I showed how to prevent a user from pasting Images from the Clipboard into CKEditor. This post is of a similar nature but is designed to ensure that users don’t paste images […]
[…] do support it, the images are only pasted as a PNG data URI. I have explained data URI images in a previous post, so check that out if you are unfamiliar with […]