Прошу прощения за такую большую задержку, но проект большой и частей много... Я вывел аспекты, которые касаются этого функционала и привел вот в этом, отдельно взятом html-файле...
<html>
<head>
<title></title>
<script>
document.addEventListener("DOMContentLoaded", function(){
// Перебираем кнопки
for(let n = 1; n <= 3; n++){
document.getElementById("BUTTON_"+n).onclick = function(){
let select = window.getSelection();
if(select.isCollapsed){
// Ни одного выделенияя нет
}
else {
let pressButton = this.getAttribute("data-tagName");
let countSelected = 0;
// Перебераем выделения
for(let n = 0; n < select.rangeCount; n++){
let range = select.getRangeAt(n);
let parentElem = range.commonAncestorContainer.parentNode;
let parentElemСhangeable = range.commonAncestorContainer;
// Выделение в нашем блоке
for(let q = 0; q <= q+1; q++){
if(parentElemСhangeable.id == "CONTENT"){
let newNode = document.createElement(pressButton);
newNode.appendChild(range.cloneContents());
range.insertNode(newNode);
range.setStartAfter(newNode);
range.deleteContents();
break;
}
else {
parentElemСhangeable = parentElemСhangeable.parentNode;
}
if(parentElemСhangeable.tagName == "BODY"){
break;
}
}
}
}
}
}
});
</script>
</head>
<body>
<div id="CONTENT" contenteditable="true" style="display:inline-block; border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0; min-height: 10em;">
Какое-то длинное высказывание, как вводная часть текста... Выдели меня... Выдели меня... Выдели меня... Выдели меня...
</div>
<div>
<button id="BUTTON_1" data-tagName="H1" style="margin-right: 0.5em;">Заголовок 1</button>
<button id="BUTTON_2" data-tagName="H2" style="margin-right: 0.5em;">Заголовок 2</button>
<button id="BUTTON_3" data-tagName="H3">Заголовок 3</button>
</div>
</body>
</html>