Sindbad~EG File Manager
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Jenish Creatives Editor</title>
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
<style>
[contenteditable="true"] {
min-height: 150px;
border: 1px solid #ced4da;
padding: 0.75rem;
border-radius: 0.375rem;
}
</style>
</head>
<body>
<div class="container py-5">
<h2 class="mb-4">Jenish Creatives Editor</h2>
<!-- TOOLBAR -->
<div class="jenish-text-editor-toolbar mb-3">
<div class="btn-group me-2">
<button type="button" class="btn btn-sm btn-light" onclick="formatText('about_intro', 'bold')"><b>B</b></button>
<button type="button" class="btn btn-sm btn-light" onclick="formatText('about_intro', 'italic')"><i>I</i></button>
<button type="button" class="btn btn-sm btn-light" onclick="formatText('about_intro', 'underline')"><u>U</u></button>
</div>
<div class="btn-group me-2">
<button type="button" class="btn btn-sm btn-light" onclick="undo('about_intro')"><i class="fas fa-undo"></i></button>
<button type="button" class="btn btn-sm btn-light" onclick="redo('about_intro')"><i class="fas fa-redo"></i></button>
</div>
<div class="btn-group me-2">
<select class="form-select form-select-sm" onchange="applyHeading('about_intro', this.value); this.value=''">
<option value="">Heading</option>
<option value="h1">H1</option>
<option value="h2">H2</option>
<option value="h3">H3</option>
<option value="p">Paragraph</option>
</select>
</div>
<div class="btn-group me-2">
<select class="form-select form-select-sm" onchange="applyColor('about_intro', this.value); this.value=''">
<option value="">Colors</option>
<option value="text-primary">Primary</option>
<option value="text-secondary">Secondary</option>
<option value="text-success">Success</option>
<option value="text-danger">Danger</option>
<option value="text-warning">Warning</option>
<option value="text-info">Info</option>
<option value="text-dark">Dark</option>
</select>
</div>
<div class="dropdown me-2">
<button class="btn btn-sm btn-light dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-link"></i>
</button>
<div class="dropdown-menu p-3" style="width: 300px;">
<div class="mb-2">
<input type="text" class="form-control form-control-sm" id="link_text_about_intro" placeholder="Link Text (optional)">
</div>
<div class="mb-2">
<input type="url" class="form-control form-control-sm" id="link_url_about_intro" placeholder="https://example.com" required>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="link_new_tab_about_intro">
<label class="form-check-label" for="link_new_tab_about_intro">Open in new tab</label>
</div>
<button type="button" class="btn btn-primary btn-sm w-100" onclick="applyLink('about_intro')">Insert Link</button>
</div>
</div>
</div>
<!-- EDITABLE CONTENT -->
<div id="editable_about_intro" class="form-control" contenteditable="true">
Type your content here...
</div>
<input type="hidden" id="about_intro" name="about_intro" />
</div>
<!-- Bootstrap Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Rich Text Logic -->
<script>
const editorHistory = {};
const editorHistoryIndex = {};
function saveHistory(editorId) {
if (!editorHistory[editorId]) {
editorHistory[editorId] = [];
editorHistoryIndex[editorId] = -1;
}
const content = document.getElementById(`editable_${editorId}`).innerHTML;
if (editorHistory[editorId][editorHistoryIndex[editorId]] !== content) {
editorHistoryIndex[editorId]++;
editorHistory[editorId].splice(editorHistoryIndex[editorId]);
editorHistory[editorId].push(content);
}
}
function undo(editorId) {
if (editorHistoryIndex[editorId] > 0) {
editorHistoryIndex[editorId]--;
document.getElementById(`editable_${editorId}`).innerHTML = editorHistory[editorId][editorHistoryIndex[editorId]];
}
}
function redo(editorId) {
if (editorHistoryIndex[editorId] < editorHistory[editorId].length - 1) {
editorHistoryIndex[editorId]++;
document.getElementById(`editable_${editorId}`).innerHTML = editorHistory[editorId][editorHistoryIndex[editorId]];
}
}
function formatText(editorId, tag) {
saveHistory(editorId);
document.execCommand(tag, false, null);
}
function applyHeading(editorId, tag) {
saveHistory(editorId);
document.execCommand('formatBlock', false, tag);
}
function applyColor(editorId, bootstrapClass) {
saveHistory(editorId);
const selection = window.getSelection();
if (!selection.rangeCount) return;
const range = selection.getRangeAt(0);
const span = document.createElement("span");
span.className = bootstrapClass;
span.appendChild(range.extractContents());
range.insertNode(span);
// Move cursor after span
selection.removeAllRanges();
const newRange = document.createRange();
newRange.setStartAfter(span);
selection.addRange(newRange);
}
function applyLink(editorId) {
const url = document.getElementById(`link_url_${editorId}`).value.trim();
const text = document.getElementById(`link_text_${editorId}`).value.trim();
const newTab = document.getElementById(`link_new_tab_${editorId}`).checked;
if (!url) {
alert('Please enter a URL.');
return;
}
const selection = window.getSelection();
let linkHTML;
if (selection.toString() || text) {
const linkText = text || selection.toString();
linkHTML = `<a href="${url}"${newTab ? ' target="_blank"' : ''}>${linkText}</a>`;
document.execCommand('insertHTML', false, linkHTML);
} else {
document.execCommand('insertHTML', false, `<a href="${url}"${newTab ? ' target="_blank"' : ''}>${url}</a>`);
}
document.getElementById(`link_url_${editorId}`).value = '';
document.getElementById(`link_text_${editorId}`).value = '';
document.getElementById(`link_new_tab_${editorId}`).checked = false;
}
</script>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists