JSFiddle - React, Tailwind, and code Playground
HTML
<p> a foo </p>
<p> another bar </p>
<input type="button" onclick="wrapInSpan(window.getSelection());" value="Click!"/>
CSS
span{
font-weight:bold;
}
JavaScript
window.rangeIntersectsNode = function(range, node) {
var nodeRange;
if (range.intersectsNode) {
return range.intersectsNode(node);
} else {
nodeRange = node.ownerDocument.createRange();
try {
nodeRange.selectNode(node);
} catch (e) {
nodeRange.selectNodeContents(node);
}
return range.compareBoundaryPoints(Range.END_TO_START, nodeRange) == -1 && range.compareBoundaryPoints(Range.START_TO_END, nodeRange) == 1;
}
}
window.getSelectedElementTags = function(win) {
var range, sel, elmlist, treeWalker, containerElement;
sel = win.getSelection();
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0);
}
if (range) {
containerElement = range.commonAncestorContainer;
if (containerElement.nodeType != 1) {
containerElement = containerElement.parentNode;
}
treeWalker = win.document.createTreeWalker(
containerElement, NodeFilter.SHOW_TEXT, function(node) {
return rangeIntersectsNode(range, node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
}, false);
elmlist = [treeWalker.currentNode];
while (treeWalker.nextNode()) {
elmlist.push(treeWalker.currentNode);
}
return (elmlist);
}
}
window.wrapInSpan = function(selObj) {
var range = selObj.getRangeAt(0);
var tempElement;
var selectedArr = getSelectedElementTags(window);
for (var i = 2; i < (selectedArr.length - 1); i++) {
tempElement = document.createElement("span");
tempElement.innerHTML = selectedArr[i].nodeValue;
selectedArr[i].parentElement.replaceChild(tempElement, selectedArr[i])
}
var sC = range.startContainer;
if (selectedArr.length == 2) {
if (sC.nodeType == 3) {
tempElement = document.createElement("span");
tempElement.innerHTML = sC.nodeValue.substring(range.startOffset, range.endOffset);
...