2

I'm trying to drop the cursor at a specific character position in a contenteditable node, and the code is working perfectly in Chrome. But in Firefox when I place the cursor it locks the cursor in position so when I type it appears to by typing right to left (so typing "hello world" would instead yield "dlrow olleh"

It wasn't obvious what was happening until I tried using the arrow keys and realized that it wasn't in RTL mode, but rather locking the position of the cursor. The backspace key does seem to work correctly though, and when I click somewhere else the cursor moves as expected and the functionality returns to normal. I'm not sure if this is expected behavior in firefox, or what I'm doing wrong. (again, in Chrome I can start typing after the cursor has been placed and the behavior is as I would expect)

I originally wrote this using rangy, but when that failed (with the above results) I tried using code found in this comment, pasted below:

function getTextNodesIn(node) {
    var textNodes = [];
    if (node.nodeType == 3) {
        textNodes.push(node);
    } else {
        var children = node.childNodes;
        for (var i = 0, len = children.length; i < len; ++i) {
            textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
        }
    }
    return textNodes;
}

function setSelectionRange(el, start, end) {
    if (document.createRange && window.getSelection) {
        var range = document.createRange();
        range.selectNodeContents(el);
        var textNodes = getTextNodesIn(el);
        var foundStart = false;
        var charCount = 0, endCharCount;

        for (var i = 0, textNode; textNode = textNodes[i++]; ) {
            endCharCount = charCount + textNode.length;
            if (!foundStart && start >= charCount
                    && (start < endCharCount ||
                    (start == endCharCount && i < textNodes.length))) {
                range.setStart(textNode, start - charCount);
                foundStart = true;
            }
            if (foundStart && end <= endCharCount) {
                range.setEnd(textNode, end - charCount);
                break;
            }
            charCount = endCharCount;
        }

        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (document.selection && document.body.createTextRange) {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(true);
        textRange.moveEnd("character", end);
        textRange.moveStart("character", start);
        textRange.select();
    }
}

This is getting called immediately after content is inserted into the contenteditable div in order to restore the cursor position.

Thanks!

Community
  • 1
  • 1
Holy Crap
  • 360
  • 1
  • 10

0 Answers0