kokeksibir
kokeksibir

Reputation: 1765

insertHTML unwraps div while inserting when selection is inside a node

In a contenteditable element, when execCommand is called with command insertHTML, if selection is inside a node command unwraps the div tag around the inserted html segment.

Sample HTML Code block is as follows:

<div id="editable" contenteditable="true">
    <div>Some text</div>
    <div>Yet another</div>
    <div>and other</div>
</div>
<input id="insert" type="button" value="Insert Segment">

and let javascript handling insertion be as follows

$('#insert').on('mousedown', function (e) { //that is to save selection on blur
    e.preventDefault(); 
}).on('click', function () { // this inserts the sample html segment
    document.execCommand('insertHTML', false, 
    '<div class="new-segment">Text inside Segment</div>');
});

Live example at http://jsfiddle.net/TE4Y6/ Follow the scenario below:

result: New div with gray background contains "Text Inside Segment" inserted

result: it inserts only the content of segment not surrounding div

expected: New div with gray background contains "Text Inside Segment" inserted

result: it inserts only the content of segment not surrounding div

expected: New div with gray background contains "Text Inside Segment" inserted

result: New div with gray background contains "Text Inside Segment" inserted

I have tried to automatically insert <br> before inserted segment It fixes 3rd step though inserts redundant space.

Do you have any suggestions?

Upvotes: 2

Views: 1827

Answers (2)

Amiris Ni&#241;o
Amiris Ni&#241;o

Reputation: 71

It seems to be an issue with Chromium. You can follow the issue at https://code.google.com/p/chromium/issues/detail?id=122062

Upvotes: 1

Alexey Lebedev
Alexey Lebedev

Reputation: 12197

You can try Range.insertNode. Proof of concept: http://jsfiddle.net/GYRLf/

var sel = window.getSelection();
if (sel.rangeCount) {
    var range = sel.getRangeAt(0);
    range.insertNode(yourDivElement);
}

A big disadvantage of this approach is that it breaks undo.


UPD. I think I found a workaround: http://jsfiddle.net/2LCtd/

document.execCommand('insertHTML', false,
    '<div class="new-segment">' +
        '<h6 class="killme">' + html + '</h6>' +
     '</div>'
);
$('.killme').contents().unwrap();

When you add a header inside the div WebKit stops merging the div with surroundings. And because the text content doesn't change when you later remove the header, the browser can undo correctly.

Upvotes: 2

Related Questions