jakiestfu / Medium.js

A tiny JavaScript library for making contenteditable beautiful (Like Medium's editor)
http://jakiestfu.github.io/Medium.js/
4.39k stars 403 forks source link

Firefox: Selecting all and typing a new text removes <p> tags #207

Open shardator opened 7 years ago

shardator commented 7 years ago

When I select all in a medium.js rich editor div, and type something (even in the demo http://jakiestfu.github.io/Medium.js/docs/) the div gets all <p> tags removed, and raw text is placed in the div. After that it is only a simple plain text editor without paragraphs and any formatting, until I clear it, unfocus it and go back.

The problem is non-existent in Chrome.

    new Medium({
        element:     document.getElementById('task-edit-1'),
        mode:        Medium.richMode,
        autoHR:      false,
        placeholder: 'What to do next...'
    });
shardator commented 7 years ago

This fixed it for me for now (external fix):

    document.getElementById('task-edit-1').oninput = function() {
        // medium.js fix #1: Full selection override removes the <p> elements
        for (var i = 0; i < this.childNodes.length; i++) {
            var node = this.childNodes[i];
            if (node.nodeType == Node.TEXT_NODE) {
                var text  = node.textContent;
                if (text.trim().length) {
                    var el    = document.createElement("p");
                    var range = document.createRange();
                    var sel   = window.getSelection();

                    var selStart = sel.getRangeAt(0).startOffset;

                    var textNode = document.createTextNode(text);
                    el.appendChild(textNode);
                    this.insertBefore(el, node);
                    this.removeChild(node);

                    range.setStart(textNode, 1);
                    range.collapse(true);
                    sel.removeAllRanges();
                    sel.addRange(range);
                } else {
                    this.removeChild(node);                            
                }
            }
        }
    };