1

I have a div that is contenteditable but I don't want to allow users to paste or drop formatted content into the div as this will - very likely - break the layout of the page.

The question how to handle HTML content that is pasted into such a div has already been raised several times and I was able to solve this problem as described here:

Javascript trick for 'paste as plain text` in execCommand

In one of the comments of the above question the point was raised that - in order to avoid HTML formatted content in the div at all - one needs to handle dropped content as well.

I need to support FF, Chrome, Edge and IE11. For all but IE11 I was able to implement a custom drop handler:

$("div[contenteditable=true]").on('drop', function(e) {
    e.preventDefault();
    var text = e.originalEvent.dataTransfer.types.indexOf && e.originalEvent.dataTransfer.types.indexOf('text/plain') >= 0 ? e.originalEvent.dataTransfer.getData('text/plain') :  e.originalEvent.dataTransfer.getData('Text');
    var range;
    if (!document.caretRangeFromPoint) { // IE11 doesn't support caretRangeFromPoint
        range = document.createRange();
        range.setStart(e.currentTarget, 0);
        range.setEnd(e.currentTarget, 0);
    } else {
        range = document.caretRangeFromPoint(e.originalEvent.clientX, e.originalEvent.clientY);
    }
    _insertText(text, range);
});

function _insertText(text, range) { 
    range.deleteContents();
    var textNode = document.createTextNode(text);
    range.insertNode(textNode);
    range.selectNodeContents(textNode);
    range.collapse(false);

    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h4 style="color:red">Drag Me</h4>
<div style="border: 1px solid;" contenteditable="true">Drop here</div>
</body>

https://jsfiddle.net/m25z6ch6/

As IE11 doesn't support document.caretRangeFromPoint I already tried to manually create a range as can be seen in the above snippet like this:

range = document.createRange();
range.setStart(e.currentTarget, 0);
range.setEnd(e.currentTarget, 0);

But This only works for dropping the content at the start of the already existing text. If I want to drop content into already existing text (e.g. between "Drop" and "here" in the above example), I somehow need to compute the offset to use. But I can't figure out how to do this for IE.

Is there a way to create a range object with correct offset given the information in a drop event (e.g. x,y coordinates and/or drop target element)?

Or is there any other way to customize the dropped content in order to allow plain text only for IE11?

dpr
  • 10,591
  • 3
  • 41
  • 71
  • I just noticed that the above snippet is not working for recent FF anymore although implemented according to documentation: https://developer.mozilla.org/de/docs/Web/API/document/caretRangeFromPoint However the question remains the same – dpr Jan 30 '18 at 14:02
  • `Drop` from where ?`Contenteditable`...? – Nikhil Ghuse Feb 01 '18 at 14:02
  • @NikhilGhuse have a look at the fiddle. Try to drag the text that says “drag me” into the contenteditable. – dpr Feb 01 '18 at 17:43

0 Answers0