Search code examples
javascriptfirefoxwysiwygcontenteditableexeccommand

execCommand bold fails in Firefox when all text is selected


I'm setting up to do some simple WYSIWYG editing using JavaScript, and I've run into an issue in Firefox that I don't get in Chrome or IE (recent versions of all). When all the text in my contentEditable span is selected, if I attempt to make it bold using document.execCommand('bold',false,null), I receive a rather nondescript error message: "NS_ERROR_FAILURE: Failure"

Here's some simple example code to easily reproduce the issue:

<html>
    <head>
        <script>
            function start(){

                var edit = document.getElementById('edit');
                edit.contentEditable = true;

                var button = document.getElementById('button');
                button.onclick = function(){

                    // Get the editable span
                    var edit = document.getElementById('edit');

                    // Select the contents of the span
                    var range = document.createRange();
                    range.selectNodeContents(edit);
                    var selection = window.getSelection();
                    selection.removeAllRanges();
                    selection.addRange(range);

                    // Make the text bold
                    document.execCommand('bold',false,null);

                }

            }
        </script>
    </head>
    <body onload="start();">
        <span id='edit'>Click on the button</span>
        <button id='button'>Bold It All!</button>
    </body>
</html>

So, what am I doing wrong here? Have I just run into a bug? If so, can anyone suggest a work-around solution?


Solution

  • This is a bug. Consider filing it. In short:

    • The editor will attempt to wrap the <span> with a <b> (or another <span> when useCSS).
    • This would remove the <span>.
    • Therefore the code checks that the parent of the <span> is editable, which it isn't.
    • Boom!

    Work-around: contenteditable="true" a real block element like <div>.