Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to keep execCommand("insertHTML") from removing attributes in chrome?

Tags:

Context is Chrome 37.0.2062.120 m.

I'm using execCommand to insert html into an editable div. My execCommand call looks like this:

function insertHTML(){     document.execCommand('insertHTML', false, '<span id="myId">hi</span>'); } 

When the editable div looks like this:

<div contenteditable="true">     some [insertion point] content </div>  

and I use execCommand to insert html into a contenteditable div, all of the attributes of the HTML are inserted as expected and I end up with this:

<div contenteditable="true">     some <span id="myId">hi</span> content </div>  

When, however, I insert the exact same html into this structure:

<div contenteditable="true">     some content     <div>more [insertion point] content</div> </div> 

The attributes are removed from the span being inserted and it ends up looking like this:

<div contenteditable="true">     some content     <div>more <span style="font-size: 10pt;">hi</span> content</div> </div> 

Is there any way to keep this from happening?

like image 663
sonicblis Avatar asked Sep 19 '14 20:09

sonicblis


1 Answers

In this particular case I would suggest using Range.insertNode instead, which will give you total control of what gets inserted:

function insertHTML() {     var sel, range;     if (window.getSelection && (sel = window.getSelection()).rangeCount) {         range = sel.getRangeAt(0);         range.collapse(true);         var span = document.createElement("span");         span.id = "myId";         span.appendChild( document.createTextNode("hi") );         range.insertNode(span);          // Move the caret immediately after the inserted span         range.setStartAfter(span);         range.collapse(true);         sel.removeAllRanges();         sel.addRange(range);     } } 

function isOrIsAncestorOf(ancestor, descendant) {    var n = descendant;    while (n) {      if (n === ancestor) {        return true;      } else {        n = n.parentNode;      }    }    return false;  }    function nodeContainsSelection(node) {    var sel, range;    if (window.getSelection && (sel = window.getSelection()).rangeCount) {      range = sel.getRangeAt(0);      return isOrIsAncestorOf(node, range.commonAncestorContainer);    }    return false;  }    function insertHTML() {    var sel, range;    if (window.getSelection && (sel = window.getSelection()).rangeCount) {      range = sel.getRangeAt(0);      range.collapse(true);      var span = document.createElement("span");      span.id = "myId";      span.appendChild( document.createTextNode("hi") );      range.insertNode(span);        // Move the caret immediately after the inserted span      range.setStartAfter(span);      range.collapse(true);      sel.removeAllRanges();      sel.addRange(range);    }  }    window.onload = function() {    document.getElementById("inserter").onmousedown = function() {      var editor = document.getElementById("editor");      if (nodeContainsSelection(editor)) {        insertHTML();        return false;      }    };  };
span {    font-weight: bold;    color: green;  }
<input type="button" id="inserter" value="Insert span">  <div contenteditable="true" id="editor">      some content  </div>
like image 168
Tim Down Avatar answered Oct 02 '22 14:10

Tim Down