|
<!DOCTYPE html> |
|
<html lang="fa" dir="rtl"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>ویرایشگر متن پیشرفته با CKEditor</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;200;300;400;500;600;700;800;900&display=swap'); |
|
|
|
body { |
|
font-family: 'Vazirmatn', sans-serif; |
|
} |
|
|
|
.ck.ck-editor__editable:not(.ck-editor__nested-editable) { |
|
min-height: 500px; |
|
} |
|
|
|
.dark-mode { |
|
background-color: #1a202c; |
|
color: #f7fafc; |
|
} |
|
|
|
.dark-mode .ck.ck-toolbar { |
|
background-color: #2d3748 !important; |
|
border-color: #4a5568 !important; |
|
} |
|
|
|
.dark-mode .ck.ck-editor__main>.ck-editor__editable { |
|
background-color: #2d3748 !important; |
|
border-color: #4a5568 !important; |
|
color: #f7fafc !important; |
|
} |
|
|
|
.dark-mode .ck.ck-button:not(.ck-disabled):hover, |
|
.dark-mode .ck.ck-button.ck-on, |
|
.dark-mode a.ck.ck-button.ck-on, |
|
.dark-mode .ck.ck-button.ck-on:hover { |
|
background-color: #4a5568 !important; |
|
} |
|
|
|
.dark-mode .ck.ck-dropdown__panel { |
|
background-color: #2d3748 !important; |
|
border-color: #4a5568 !important; |
|
} |
|
|
|
.dark-mode .ck.ck-list__item:hover:not(.ck-disabled) { |
|
background-color: #4a5568 !important; |
|
} |
|
|
|
.dark-mode .ck.ck-input-text { |
|
background-color: #2d3748 !important; |
|
border-color: #4a5568 !important; |
|
color: #f7fafc !important; |
|
} |
|
|
|
.dark-mode .ck.ck-label { |
|
color: #f7fafc !important; |
|
} |
|
|
|
.fullscreen { |
|
position: fixed !important; |
|
top: 0 !important; |
|
left: 0 !important; |
|
right: 0 !important; |
|
bottom: 0 !important; |
|
z-index: 1000 !important; |
|
background: white; |
|
padding: 1rem; |
|
} |
|
|
|
.dark-mode .fullscreen { |
|
background: #2d3748; |
|
} |
|
|
|
.fullscreen .ck.ck-editor__main>.ck-editor__editable { |
|
min-height: calc(100vh - 100px) !important; |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-100"> |
|
<div class="container mx-auto p-4 max-w-6xl"> |
|
<h1 class="text-3xl font-bold text-center mb-6 text-blue-600">ویرایشگر متن پیشرفته با CKEditor</h1> |
|
|
|
<div class="flex justify-between items-center mb-4"> |
|
<div class="flex space-x-2 space-x-reverse"> |
|
<button id="dark-mode-toggle" class="p-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700" title="حالت تاریک/روشن"> |
|
<i class="fas fa-moon"></i> |
|
</button> |
|
<button id="fullscreen-toggle" class="p-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700" title="حالت تمام صفحه"> |
|
<i class="fas fa-expand"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="flex space-x-2 space-x-reverse"> |
|
<button id="save-html" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"> |
|
<i class="fas fa-save ml-1"></i> ذخیره به عنوان HTML |
|
</button> |
|
<button id="save-pdf" class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"> |
|
<i class="fas fa-file-pdf ml-1"></i> ذخیره به عنوان PDF |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div id="editor-container"> |
|
|
|
</div> |
|
|
|
<div class="mt-6 flex justify-between items-center"> |
|
<div class="text-sm text-gray-500 dark:text-gray-400"> |
|
<span id="word-count">کلمات: 0</span> | |
|
<span id="character-count">کاراکترها: 0</span> |
|
</div> |
|
<div class="text-sm text-gray-500 dark:text-gray-400" id="current-time"> |
|
|
|
</div> |
|
</div> |
|
|
|
<div class="mt-4 text-center text-gray-500 dark:text-gray-400 text-sm"> |
|
ویرایشگر متن پیشرفته با CKEditor - تمام حقوق محفوظ است © 2023 |
|
</div> |
|
</div> |
|
|
|
|
|
<script src="https://cdn.ckeditor.com/ckeditor5/36.0.1/super-build/ckeditor.js"></script> |
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> |
|
|
|
<script> |
|
|
|
CKEDITOR.ClassicEditor.create(document.getElementById("editor-container"), { |
|
toolbar: { |
|
items: [ |
|
'undo', 'redo', |
|
'|', 'heading', |
|
'|', 'fontfamily', 'fontsize', 'fontColor', 'fontBackgroundColor', |
|
'|', 'bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript', |
|
'|', 'alignment', |
|
'|', 'bulletedList', 'numberedList', 'outdent', 'indent', |
|
'|', 'link', 'uploadImage', 'blockQuote', 'insertTable', |
|
'|', 'code', 'codeBlock', 'htmlEmbed', |
|
'|', 'horizontalLine', 'pageBreak', 'specialCharacters', |
|
'|', 'sourceEditing' |
|
], |
|
shouldNotGroupWhenFull: true |
|
}, |
|
language: 'fa', |
|
list: { |
|
properties: { |
|
styles: true, |
|
startIndex: true, |
|
reversed: true |
|
} |
|
}, |
|
heading: { |
|
options: [ |
|
{ model: 'paragraph', title: 'پاراگراف', class: 'ck-heading_paragraph' }, |
|
{ model: 'heading1', view: 'h1', title: 'سرتیتر 1', class: 'ck-heading_heading1' }, |
|
{ model: 'heading2', view: 'h2', title: 'سرتیتر 2', class: 'ck-heading_heading2' }, |
|
{ model: 'heading3', view: 'h3', title: 'سرتیتر 3', class: 'ck-heading_heading3' }, |
|
{ model: 'heading4', view: 'h4', title: 'سرتیتر 4', class: 'ck-heading_heading4' }, |
|
{ model: 'heading5', view: 'h5', title: 'سرتیتر 5', class: 'ck-heading_heading5' }, |
|
{ model: 'heading6', view: 'h6', title: 'سرتیتر 6', class: 'ck-heading_heading6' } |
|
] |
|
}, |
|
fontFamily: { |
|
options: [ |
|
'Vazirmatn, sans-serif', |
|
'Arial, Helvetica, sans-serif', |
|
'Courier New, Courier, monospace', |
|
'Georgia, serif', |
|
'Times New Roman, Times, serif', |
|
'Trebuchet MS, Helvetica, sans-serif', |
|
'Verdana, Geneva, sans-serif', |
|
'default' |
|
], |
|
supportAllValues: true |
|
}, |
|
fontSize: { |
|
options: [ 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 ], |
|
supportAllValues: true |
|
}, |
|
htmlSupport: { |
|
allow: [ |
|
{ |
|
name: /.*/, |
|
attributes: true, |
|
classes: true, |
|
styles: true |
|
} |
|
] |
|
}, |
|
htmlEmbed: { |
|
showPreviews: true |
|
}, |
|
link: { |
|
decorators: { |
|
addTargetToExternalLinks: true, |
|
defaultProtocol: 'https://', |
|
toggleDownloadable: { |
|
mode: 'manual', |
|
label: 'قابل دانلود', |
|
attributes: { |
|
download: 'file' |
|
} |
|
} |
|
} |
|
}, |
|
mention: { |
|
feeds: [ |
|
{ |
|
marker: '@', |
|
feed: [ |
|
'@apple', '@bears', '@brownie', '@cake', '@cake', '@candy', '@canes', '@chocolate', '@cookie', '@cotton', '@cream', |
|
'@cupcake', '@danish', '@donut', '@dragée', '@fruitcake', '@gingerbread', '@gummi', '@ice', '@jelly-o', |
|
'@liquorice', '@macaroon', '@marzipan', '@oat', '@pie', '@plum', '@pudding', '@sesame', '@snaps', '@soufflé', |
|
'@sugar', '@sweet', '@topping', '@wafer' |
|
], |
|
minimumCharacters: 1 |
|
} |
|
] |
|
}, |
|
removePlugins: [ |
|
'CKBox', |
|
'CKFinder', |
|
'EasyImage', |
|
'RealTimeCollaborativeComments', |
|
'RealTimeCollaborativeTrackChanges', |
|
'RealTimeCollaborativeRevisionHistory', |
|
'PresenceList', |
|
'Comments', |
|
'TrackChanges', |
|
'TrackChangesData', |
|
'RevisionHistory', |
|
'Pagination', |
|
'WProofreader', |
|
'MathType' |
|
] |
|
}).then(editor => { |
|
window.editor = editor; |
|
|
|
|
|
editor.model.document.on('change:data', () => { |
|
updateCounts(); |
|
}); |
|
|
|
|
|
editor.setData('<p style="text-align: right;">متن خود را اینجا بنویسید...</p>'); |
|
}).catch(error => { |
|
console.error(error); |
|
}); |
|
|
|
|
|
function updateCounts() { |
|
if (!window.editor) return; |
|
|
|
const text = window.editor.getData().replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim(); |
|
const words = text ? text.split(/\s+/).filter(word => word.length > 0).length : 0; |
|
const characters = text.length; |
|
|
|
document.getElementById('word-count').textContent = `کلمات: ${words}`; |
|
document.getElementById('character-count').textContent = `کاراکترها: ${characters}`; |
|
} |
|
|
|
|
|
function updateTime() { |
|
const now = new Date(); |
|
const hours = now.getHours().toString().padStart(2, '0'); |
|
const minutes = now.getMinutes().toString().padStart(2, '0'); |
|
document.getElementById('current-time').textContent = `زمان: ${hours}:${minutes}`; |
|
} |
|
|
|
|
|
updateTime(); |
|
setInterval(updateTime, 60000); |
|
|
|
|
|
document.getElementById('dark-mode-toggle').addEventListener('click', function() { |
|
document.body.classList.toggle('dark-mode'); |
|
const icon = this.querySelector('i'); |
|
if (document.body.classList.contains('dark-mode')) { |
|
icon.classList.replace('fa-moon', 'fa-sun'); |
|
} else { |
|
icon.classList.replace('fa-sun', 'fa-moon'); |
|
} |
|
}); |
|
|
|
|
|
document.getElementById('fullscreen-toggle').addEventListener('click', function() { |
|
const container = document.getElementById('editor-container'); |
|
container.classList.toggle('fullscreen'); |
|
|
|
const icon = this.querySelector('i'); |
|
if (container.classList.contains('fullscreen')) { |
|
icon.classList.replace('fa-expand', 'fa-compress'); |
|
} else { |
|
icon.classList.replace('fa-compress', 'fa-expand'); |
|
} |
|
}); |
|
|
|
|
|
document.getElementById('save-html').addEventListener('click', function() { |
|
if (!window.editor) return; |
|
|
|
const content = window.editor.getData(); |
|
const blob = new Blob([content], { type: 'text/html' }); |
|
const url = URL.createObjectURL(blob); |
|
|
|
const a = document.createElement('a'); |
|
a.href = url; |
|
a.download = 'document.html'; |
|
a.click(); |
|
|
|
URL.revokeObjectURL(url); |
|
}); |
|
|
|
|
|
document.getElementById('save-pdf').addEventListener('click', function() { |
|
if (!window.editor) return; |
|
|
|
|
|
const editorContent = document.querySelector('.ck.ck-editor__main .ck-editor__editable'); |
|
|
|
html2canvas(editorContent).then(canvas => { |
|
const imgData = canvas.toDataURL('image/png'); |
|
const pdf = new jspdf.jsPDF({ |
|
orientation: 'portrait', |
|
unit: 'mm' |
|
}); |
|
|
|
|
|
const imgWidth = 210; |
|
const imgHeight = canvas.height * imgWidth / canvas.width; |
|
|
|
pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight); |
|
pdf.save('document.pdf'); |
|
}); |
|
}); |
|
|
|
|
|
document.addEventListener('keydown', function(e) { |
|
|
|
if (e.ctrlKey && e.key === 's') { |
|
e.preventDefault(); |
|
document.getElementById('save-html').click(); |
|
} |
|
|
|
|
|
if (e.ctrlKey && e.key === 'p') { |
|
e.preventDefault(); |
|
document.getElementById('save-pdf').click(); |
|
} |
|
|
|
|
|
if (e.ctrlKey && e.key === 'd') { |
|
e.preventDefault(); |
|
document.getElementById('dark-mode-toggle').click(); |
|
} |
|
|
|
|
|
if (e.key === 'F11') { |
|
e.preventDefault(); |
|
document.getElementById('fullscreen-toggle').click(); |
|
} |
|
}); |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MrHesam/ckeditor" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |