0

I'm using a bit of javascript written by The Great and Powerful Oz Tim Down that inserts things at the caret. It works great, but how can I restrict the function to only operate within a div with a class name of "editor-text"?

Edit: It must also work within other elements (such as H1) that may be within the .editor-text div.

Edit2: Must also work on new lines. See http://jsfiddle.net/j5mv219L/

The Live Demo: http://jsfiddle.net/wfo7gcvh/

The Code:

function pasteHtmlAtCaret(html) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(),
                node, lastNode;
            while ((node = el.firstChild)) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(html);
    }
}
Community
  • 1
  • 1
kthornbloom
  • 3,660
  • 2
  • 31
  • 46

1 Answers1

0

You can get the node that has the selection, and check if it has the class or is the child of an element that has the class etc

function pasteHtmlAtCaret(html, selector) {
    var sel, range, parent, node = null;

    if (document.selection) {
        node = document.selection.createRange().parentElement();
    } else {
        var selection = window.getSelection();
        if (selection.rangeCount > 0) {
            node = selection.getRangeAt(0).startContainer;
            if (node !== $(node).closest(selector).get(0)) {
                node = node.parentNode;
            }
        }
    }



    if (node && $(node).closest(selector).length > 0 && window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(),
                node, lastNode;
            while ((node = el.firstChild)) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        document.selection.createRange().pasteHTML(html);
    }
}

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Thanks adeneo, that does indeed work. I was hoping to just edit the original pasteHTMLAtCaret function, rather than the code that calls that function since it is used in several places though. – kthornbloom Mar 02 '15 at 20:24
  • I know this was answered awhile back, but I discovered a bug with this method. Basically lets say you have an

    tag in there. You can't paste into it because it's reading the H1 as the parent, not the specified class: http://jsfiddle.net/kthornbloom/wfo7gcvh/4/

    – kthornbloom Mar 27 '15 at 15:09
  • I had to remove this as the answer due to the problem with the solution. I can re-mark it if it's corrected. – kthornbloom Mar 27 '15 at 20:14
  • So sorry, but I found another little issue. It doesn't work on new lines made with
    's. Any clues as to why? Here's an example: http://jsfiddle.net/j5mv219L/
    – kthornbloom Apr 02 '15 at 02:08
  • Added a fix for that as well, but you really should ask a new question whenever the parameters of the original question changes like this, instead of just removing the accepted tag every time. – adeneo Apr 02 '15 at 18:31
  • Thanks. I wasn't sure if it was better to have duplicate questions, or request edits here. – kthornbloom Apr 02 '15 at 18:41
  • Neither am I, smaller edits to bugs in the code, like this was, is probably fine here, but generally it's reccommended to ask a new question if the question itself changes, I think? – adeneo Apr 02 '15 at 18:49