Insertar text antes y después de la selección en un contenteditable

¿Hay alguna manera de insert text similar a bbcode antes y después del text seleccionado en un div satisfactorio? He visto muchas respuestas para textarea, pero el código no funciona con una div contenida. El soporte de IE no es necesario.

El enfoque que sugeriría es:

  • Obtener un range de la selección
  • Inserta un nodo de text al final del range
  • Inserte otro nodo de text al comienzo del range
  • Vuelva a seleccionar el text original

La siguiente demostración funcionará en todos los browseres principales excepto IE <= 8.

Demostración: http://jsfiddle.net/8WEru/

Código:

function surroundSelection(textBefore, textAfter) { if (window.getSelection) { var sel = window.getSelection(); if (sel.rangeCount > 0) { var range = sel.getRangeAt(0); var startNode = range.startContainer, startOffset = range.startOffset; var startTextNode = document.createTextNode(textBefore); var endTextNode = document.createTextNode(textAfter); var boundaryRange = range.cloneRange(); boundaryRange.collapse(false); boundaryRange.insertNode(endTextNode); boundaryRange.setStart(startNode, startOffset); boundaryRange.collapse(true); boundaryRange.insertNode(startTextNode); // Reselect the original text range.setStartAfter(startTextNode); range.setEndBefore(endTextNode); sel.removeAllRanges(); sel.addRange(range); } } } 

Si entiendo por sus comentarios el nuevo objective, tiene una selección y desea rodearlo con un elemento. Entonces el método de range de surroundContents debería funcionar:

 var selection = window.getSelection(); var range = selection.getRangeAt(0); var strong = document.createElement('strong'); range.surroundContents(strong);