JSFiddle - React, Tailwind, and code Playground
by Imri Paloja
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<div class="container">
<h1>Bold/Unbold Editor</h1>
<p>Select text in the editor below and use the Bold button or Ctrl+B to toggle bold formatting.</p>
<div id="editor" contenteditable="true">
<p>This is a <strong>bold text</strong> example. Select some text and try the bold toggle!</p>
<p>You can also select <strong>partially bold</strong> text and toggle it.</p>
</div>
</div>
CSS
body {
font-family: Arial, sans-serif;
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
#editor {
min-height: 150px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
margin: 10px 0;
outline: none;
}
#editor:focus {
border-color: #4a86e8;
box-shadow: 0 0 0 2px rgba(74, 134, 232, 0.2);
}
#boldButton {
padding: 5px 15px;
font-weight: bold;
cursor: pointer;
border: 1px solid #ccc;
background: white;
border-radius: 4px;
transition: all 0.2s;
}
#boldButton:hover {
background-color: #f0f0f0;
}
#boldButton.active {
background-color: #4a86e8;
color: white;
border-color: #4a86e8;
}
JavaScript
// Save and restore selection utilities
function saveSelection() {
const selection = window.getSelection();
if (selection.rangeCount === 0) return null;
return selection.getRangeAt(0).cloneRange();
}
function restoreSelection(range) {
if (!range) return;
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
// Main bold toggle function
function toggleBold() {
const editor = document.getElementById('editor');
if (!editor) {
console.error('Editor element not found');
return;
}
// Save current selection
const savedRange = saveSelection();
if (!savedRange) return;
// Check if we have a valid selection
const selection = window.getSelection();
if (selection.isCollapsed) {
// Handle cursor position (no text selected)
handleCollapsedSelection(savedRange);
restoreSelection(savedRange);
return;
}
// Check if selection is already bold
if (isSelectionBold(selection)) {
// Remove bold
removeBoldFromSelection(savedRange);
} else {
// Apply bold
applyBoldToSelection(savedRange);
}
// Restore focus to editor
editor.focus();
}
// Check if selected text is already bold
function isSelectionBold(selection) {
const range = selection.getRangeAt(0);
// Check if selection contains any non-bold text
const walker = document.createTreeWalker(
range.commonAncestorContainer.parentNode || range.commonAncestorContainer,
NodeFilter.SHOW_TEXT,
null,
false
);
let currentNode;
while (currentNode = walker.nextNode()) {
// Check if this text node is in the selection
if (!isNodeInRange(currentNode, range)) continue;
// Check if this text node has bold parent
if...