1

Topic: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

When using TinyMCE (3.5.4.1) in IE9, if I place a DIV in my content, and if that DIV has either/both Height & Width specified, IE treats it, at least partially, as a contenteditable DIV.

This means when the user comes to edit such a document in TinyMCE the first time they click in the editor IE highlights the DIV in question, and allows the user to move it - which they often do by accident. They then have to click again to edit the content inside the DIV and while they do this the DIV is outlined on the page which is a distraction.

I have seen a number of posts (e.g. http://www.tinymce.com/forum/viewtopic.php?id=3939) saying that IE fires the "controlselect" event in this case and to place the cursor within the content and return false. I eventually managed to get this example to run, but while it suppresses the initial selection of the content it then seems to become random as to whether a given click inside the content places a cursor there or not.

Is there a reliable way to make IE handle this situation like the other browsers do i.e. with no unexpected side effects from adding height/width to a DIV?

2

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

Yeah. I hate that "feature" too. But maybe it's possible to just switch contentEditable on/off on the parent body once it gets the selection event. Then when you click out side you re-enable contentEditable. Haven't had time to test that but maybe you could toy with it?

Best regards,
Spocke - Main developer of TinyMCE

3

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

spocke wrote:

Yeah. I hate that "feature" too. But maybe it's possible to just switch contentEditable on/off on the parent body once it gets the selection event. Then when you click out side you re-enable contentEditable. Haven't had time to test that but maybe you could toy with it?

I don't quite understand what you mean? When I turned contentEditable off on the DIV in question by catching the event nothing could be edited. When I left it on it selected the DIV and made it possible to move it.

Last edited by CoolKiwiBloke (2012-08-24 12:13:27)

4

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

Do it on the body. tinymce.activeEditor.getBody().contentEditable = false; then div.contentEditable = true; Then in theory the div shouldn't have any resize stuff.

Best regards,
Spocke - Main developer of TinyMCE

5

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

spocke wrote:

Do it on the body. tinymce.activeEditor.getBody().contentEditable = false; then div.contentEditable = true; Then in theory the div shouldn't have any resize stuff.

OK, that worked pretty well. Two things it doesn't do:

1) Nothing outside the DIV can be edited, I hadn't planned on having all my content within the DIV but can probably live with it.

2) Child DIVs contained within the primary DIV continue to be selectable regardless of whether contentEditable is set to true or false.

Out of curiosity why does it work this why when you disable contentEditable on the body and enable it on the primary DIV?

The code I ended up using is below.

    $(document).ready(function (){
        InstallEventHandler();
        $("body").click(function(){
            if (typeof tinymce != 'undefined' && tinymce.activeEditor != null) tinymce.activeEditor.getBody().contentEditable = true;
        });
    });

    function InstallEventHandler() {
        if (typeof tinymce != 'undefined' && tinymce.activeEditor != null) {
            var editor = tinymce.activeEditor.getBody();

            // Only IE handles this event so we don't need to limit it by browser
            editor.oncontrolselect = function(e){
                // Make the containing editor BODY not-content-editable
                editor.contentEditable = false;
                var divs = $(editor).find("div");
                divs.each(function(i){
                    // For any DIV that would have been content-editable set it true
                    if (this.style.height.length > 0 || this.style.width.length > 0 || this.style.position.length > 0) {
                        this.contentEditable = true;
                    }
                });
                // Pause and then place the cursor there the user clicked
                setTimeout("moveToText(" + e.clientX + ", " + e.clientY + ")", 1);
            };
        }
        else {
            setTimeout(function(){InstallEventHandler();}, 500);
        }
    }

    function moveToText(x, y)
    {
        var rng = tinymce.activeEditor.getBody().createTextRange();
        rng.moveToPoint(x, y);
        rng.collapse();
        rng.select();
    }

6

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

Any further comments on my implementation and other points Spocke?

7

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

OK, I have just found one further issue, when using copy and paste with this fix in place. If doing a regular paste (Ctrl-V) in IE9 it pastes the content and then selects all the content which cannot be unselected until clicking outside the editor. If using the paste button, the first click is ignored, the second click pastes the content but selects the outer DIV therefore defeating the fix.

Any thoughts?

8

Re: TinyMCE / IE9 / DIV Width/Height / ContentEditable / Prevent selection

I had a similiar IE 8, 9, 10 issue that was caused when I on a TinyMCE editor typing in text, then moved to another area on the screen, which would remove the TinyMCE and display something else.  The user was left with a cursor where they could type text into a <div>.

Solution I used was to loop through and remove any editors for I called tinyMCE.init.  (It is possible my UI to have multiple tinyMCE editors open at the same time, updating text in several areas in another iframe on the page.  - long story)  I had to set the .contentEditable = false for the getBody of the activeEditor.  Nothing else I did, including setting all <div> tags on the page to .contenteditable = false worked.

for (var i=0; i<tinymce.editors.length; i++) {
            tinymce.activeEditor.getBody().contentEditable = false;
            $('.change-bg-checkbox').remove();
            tinyMCE.execCommand('mceFocus', false, tinymce.editors[i].id); //Have to do this for IE
            tinyMCE.execCommand('mceRemoveControl',false, tinymce.editors[i].id);            
        };